@L}5 _$% l0$)$$Hȱ$ UhL" `e$$%`$%`  R@P!( L(1   Y I`  d  Ld M * @  $ % CC$$)%1 Udߥ$9%: !0 S$% DD˙`  }J)Lr d M * @  $ % CC$$)%1 Udߥ$9%: !0 S$%} DD˙`  }J)Lr J  ((  p L ()   J}L= ( L 0q A    IB JC;? D W } LL  ` W )LA!  ߰")-݆ p" } $G@LL 08`Q")<2Q0 -G$Ș݆ UL# ; p8(()(0ʥ)NQ` }$GȘ݆LU )L ݆ L GȘ ݆LL )W>Z   HH)H }p h  hyhy D L> L JJ    ! LA*` BF }7'8  M HN H` 8 Z  \LdJJ!"! GFE@F (!L }EE !E^ ^ E E7EȩEdE/EȩE  D } .L }  ;F d  ;?F7F? ( .   Z D LL d } . D  L    p  E` , d)  D L) 0BM݊L݉} ML  N݆ L NLML [ TEqEHȱEqEh 0Gȹ G} HLL GɛL  LFREE SECTORS G) *Gȩ GȽG GȌ*jj >G} C8jJ3j2CD( C202C ԠBX` N 1? l LlD:RAMDISK}.COMLu L1 L ;LHL  T`  `1  ɐ     `TU  } L ? .  t`GBJ ~DEHI B V0dV!}QDEHI VF9 ,0 ,0 s0hhL  L` H hDHEh"}DEL8HI4 0 HI,0 0  9 .G VLO#},0 L4*IJ`llD1:AUTORUN.SYSNEED MEM.SAV TO LOAD THIS FILE.D1:MEM.SAV J y08 B|DEHI$} V0 0`B;DEL`?<0LV`@ʆ v s? F0Ξ05: [ BDEHI%} VY8 B V  @  /DE `E:D1:DUP.SYSERROR-SAVING USER MEMORY ON DISKTYPE Y TO &}STILL RUN DOS B;DE J  (` 9 V⪍ ઍ  -'}LLu ÝDEHILV 9 .l 9 .l  `` s$B BH(}I|DE V BLV nB,DE JLV B V BLVDEIʩ BꭝLu  } 3E:}DISK OPERATING SYSTEM II VERSION COPYRIGHT 1984 ATARI CORP.A. DISK DIRECTORY I. FORMAT DISKB. RUN CARTRIDG*}E J. DUPLICATE DISKC. COPY FILE K. BINARY SAVED. DELETE FILE(S) L. BINARY LOADE. RENAME FILE M. RUN AT ADDRES+}SF. LOCK FILE N. CREATE MEM.SAVG. UNLOCK FILE O. DUPLICATE FILEH. WRITE DOS FILES P. FORMAT SINGLEL !N',}#"&))9(&*)/h)''-&؆莟R'S  vL/ˢ L }Insert DOS 2.0s, type Y Λx -}DEfHI 1莏#q! @ y0ɛ8A0,' ȅ 1 1ild! 1L!NO SUCH ITEMSELECT.} ITEM OR FOR MENU! 0 .z:*{}.|{ 1 0 0JB 18L%|DL/}%DIRECTORY--SEARCH SPEC,LIST FILE?[# 0 0 &|D3" 1L!NOT A DISK FILEN !B 1L!E# 1 !BD0}ED:}:1BJ|DE 1DEBHI 1 h0ߢ 0.1}  0?詛 1 y0YЛ 1 ;#L" ;#L! BL1TYPE "Y" TO DELETE...DELETE FILE SPEC2}COPY--FROM, TO?OPTION NOT ALLOWED736 FREE SECTORS COPYING---D1:DIRECK.COMl# 0|D .L/%#3}##JB|DE 1BHID#E 1#0: B 1L!#͑### B 1#c$0SY4}S1}:## # # .#Ƚ# # 𩛙## 1,#PD#ELJ- <.BJD#E 5}1 1HH 0hh|DL%1}:̳# L% #D#EL% 1 0 . .0O% 1L!WILD CARDS NOT A6}LLOWED IN DESTINATION 0 <.|K}N 2 FORMAT. t* 5) 1L!`) 0NΞ 0 L1) 1 L!BAD LOAD FILELOAD FROM WHAT FILE?) 0 ?}0#B 1L!WHAT FILE TO LOCK?) 0 0$B 1L!WHAT FILE TO UNLOCK?DUP DISK-SOURCE,DEST DRIVES?TYPE "Y" IF OK TO US@}E PROGRAM AREACAUTION: A "Y" INVALIDATES MEM.SAV.FE! +L1   `*  70 2 2A} 0.* 1 y0 0)INSERT BOTH DISKS, TYPE RETURN^, 1 y038逍 N, 1L! ,B}C, t*  Lx+, 0 ^, 1 y0 , ,0,0 ,L+ ,I0 ,Vǭ0C}Ξ, 0 }, 1 y0C,ШC, 0K'!" H H 'h h Lx+!EF 5L1L!D,I,HhD}` NOT ENOUGH ROOMINSERT SOURCE DISK,TYPE RETURNINSERT DESTINATION DISK,TYPE RETURNE}`  `8 rL1`-* 1P* 1 y0Y`hhL!NAME OF FILE TO MOVE?- 0 0|DL% <.F},^ 1 70 0 .@L# .BJ 1  DEHIB V L1 ,} 1 70,L.  G}JB|,#P#DE 1 HI BDEHHII 1 B 1 ,^ 1 70,0La- B V,#PH},^ 1 70 0L#L!-* 1P* 1 y0Yj383}mm ݭI}}`8}``|* ? ɛ,`|:-)| / 1L!`DESTINATION CANT BE DOJ}S.SYS0 0H{ 24Δ 28/L!/) 2 Π 2 0 ξK}hAΞB,0 J 1 BDEHI,HÝDE 1HIHIDELSAVE-GIVE L}FILE,START,END(,INIT,RUN)O S0 1`BDEPHI V` S0H 1 L!M}0 0 1L~0`PLEASE TYPE 1 LETTER,0`hhL! 70 1L0L<1 ,;ɛ7,"ɛ:ݦ1ݥN}A"D|ݤD|ȩ:|ȩ|ɛ,,(/+.ީ1 1,ɛ`轤{NAMEO} TOO LONG B VL!` L1I H1EΝDL1|mDiE` V0`8d/8 i:222 1 LP}!ERROR- 138ɛ+,' 20*.. өr2 1``2TOO MANY DIGITSINVALID HEXAQ}DECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8uR} ECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8u TITLE 'DOUBLE DENSITY MYDOS3 SYSTEM DISK BUILDER' ; ; Copyright 1984, Charles Marslett, Wordmark Systems ; ; Permission isT} granted by the author for any use whatsoever of this ; code, so long as this notice remains in the source code, and so ; U} long as the source to this routine, however modified or unmodified, ; is made available for a nominal cost. ; ; ; SomeV} important absolute addresses ; CIOV = $E456 ;CIO ENTRY VECTOR ; MENUP = $02E0 ;THE RUN ENTRY POINT OF "MDUP.OBJ" ; ORIGIN = W}$4800 ;GOTTA BE BIG ENOUGH TO NOT HIT EITHER COPY OF MYDOS ; ZCTR = $FA ;A GENERAL PURPOSE COUNTER BPTR = $FC ;A GENERAL PURPX}OSE POINTER ZPTR = $FE ;AND ANOTHER GENERAL PURPOSE POINTER ; ; Define the fields of IOCB $10 that I use ; ORG $0351 DS 1 Y}ICMD DS 1 DS 1 IBUF DS 4 ILEN DS 2 IAUX1 DS 1 IAUX2 DS 1 ; ; The BUILD program itself -- loads MDOS.OBJ and MDUP.OBJ into meZ}mory above ; itself, then relocates the code down over the previous version of MYDOS ; that we are running with and start[}s it up. This is how we create a new ; version of MYDOS. ; ORG ORIGIN ; START LDX #LOW[SIGNON] LDY #HIGH[SIGNON] ;LOG ON\}TO THE SCREEN JSR DMSG ; LDA #$C0 STA BPTR+1 ;POINT BPTR AT $C000 LDY #0 STY BPTR LDA #$FF STA SAVC LDX #$10 CLRC ST]}A (BPTR),Y INY BNE CLRC INC BPTR+1 DEX BNE CLRC ; LDA #HIGH[BUFFER] STA BPTR+1 ;POINT BPTR AT "BUFFER" LDA #LOW[BUFF^}ER] STA BPTR LDX #$20 LDA #0 MVLP1 STA (BPTR),Y ;FILL THE 8K BUFFER WITH $00 BYTES INY BNE MVLP1 INC BPTR+1 DEX BNE M_}VLP1 ; ; COPY NEW DOS CODE FROM FILE "MDOS.OBJ" ; LDX #LOW[MSG01] LDY #HIGH[MSG01] JSR DMSG ;ANNOUNCE WE ARE READING "D:M`}DOS.OBJ" LDY #LOW[DOSFIL] LDA #HIGH[DOSFIL] JSR LOADBF ;LOAD CONTENTS OF "MDOS.OBJ" ; ; COPY NEW DOS AND DUP CODE FROM FIa}LE "MDUP.OBJ" ; LDX #LOW[MSG02] LDY #HIGH[MSG02] JSR DMSG ;ANNOUNCE WE ARE READING "D:MDUP.OBJ" LDY #LOW[DUPFIL] LDA #Hb}IGH[DUPFIL] JSR LOADBF ;LOAD CONTENTS OF "MDUP.OBJ" ; ; MOVE BUFFER DOWN TO LOW MEMORY ; LDX #LOW[MSG03] LDY #HIGH[MSG03]c} JSR DMSG ;ANNOUNCE WE ARE RELOCATING DOS AND DUP CODE LDA #$07 STA ZPTR+1 LDA #$00 STA ZPTR ;SET DESTINATION POINTER d}TO $0700 LDA #HIGH[BUFFER] STA BPTR+1 LDA #LOW[BUFFER] STA BPTR ;SET SOURCE POINTER TO "BUFFER" ; LDY #0 MVLP2 LDA (BPTe}R),Y STA (ZPTR),Y ;COPY 256 BYTES AT A TIME UNTIL WE INY ;ARE ABOUT TO OVERWRITE BUILD ITSELF BNE MVLP2 ;(THIS IS TOO Mf}UCH, I HOPE, BUT IT WORKS) INC BPTR+1 INC ZPTR+1 LDA ZPTR+1 CMP #HIGH[START] BNE MVLP2 ; ; REINITIALIZE THE SYSTEM ; LDg}X #LOW[MSG04] LDY #HIGH[MSG04] JSR WFSTR ;ANNOUNCE STARTUP AND WAIT FOR A KEY ; JSR DOSINI ;REINITIALIZE THE NEW MYDOS ;h} LDX #0 LDA #3 STA ICMD-16 LDA #$2C STA IAUX1-16 LDA #LOW[EC] STA IBUF-16 LDA #HIGH[EC] STA IBUF+1-16 JSR CIOV ;REi}OPEN THE KEYBOARD/SCREEN "E:" DEVICE ; LDX #LOW[MSG05] LDY #HIGH[MSG05] JSR WFSTR ;ANNOUNCE WE ARE READY TO RUN THE NEW Mj}YDOS ; JMP (MENUP) ;ENTER BACK AT MENU (USE "H" TO SAVE NEW DOS) ; ; ; LOAD CONTENTS OF OBJECT FILE INTO BUFFER ; LOADBF STk}Y IBUF STA IBUF+1 LDA #$FF STA MINAD STA MINAD+1 ;SET LOW ADDRESS TO $FFFF LDA #3 STA ICMD LDA #4 STA IAUX1 LDA #0 l} STA MAXAD ;SET HIGH ADDRESS TO $0000 STA MAXAD+1 STA IAUX2 LDX #$10 JSR CIOV ;OPEN D:MDOS.OBJ OR D:MDUP.OBJ BPL GOTFIm}L LDX #LOW[NOFIL] LDY #HIGH[NOFIL] JSR DMSG ;REPORT IT IF WE CANNOT OPEN THE FILE JMP ($000A) ; GOTFIL LDA #7 ;ELSE, Sn}TA ICMD ;CHANGE COMMAND TO READ LDA #LOW[BUFAD] STA IBUF LDA #HIGH[BUFAD] ;BUFFER ADDRESS TO THAT OF LOCAL BUF. STA IBUFo}+1 LDA #2 STA ILEN LDA #0 STA ILEN+1 ;LENGTH TO 2 BYTES LDX #$10 JSR CIOV ;READ HEADER BMI INVHDR ;IF ERROR, REPORTp} IT LDA BUFAD AND BUFAD+1 CMP #$FF ;ELSE, VALID HEADER? BPL RDNXTB INVHDR LDX #LOW[NOHDR] LDY #HIGH[NOHDR] JSR DMSG ;q}IF NOT, REPORT THAT ERROR JMP ($000A) ; RDNXTB LDA #LOW[BUFAD] ;READ THE NEXT WORD PAIR (START & END ADDR) STA IBUF LDA #Hr}IGH[BUFAD] STA IBUF+1 LDA #4 STA ILEN ;SET LENGTH TO 4 BYTES LDA #0 STA ILEN+1 LDX #$10 JSR CIOV ;READ START/END ADDs}RESSES BPL RDDATA ;IF NO ERROR, LOAD THE DATA CPY #$88 ;ELSE, IS IT EOF? BNE ABORT ;IF NOT EOF, REPORT THE ERROR JMP Mt}OVER ;IF EOF, WE HAVE LOADED IT ALL, RETURN NORMALLY ; RDDATA LDA BUFAD+2 LDY BUFAD+3 CPY MAXAD+1 BCC NOTMAX ;IF THIS BLu}OCK SETS A NEW HIGH ADDRESS LOADED BNE NEWMAX CMP MAXAD BCC NOTMAX NEWMAX STY MAXAD+1 ;UPDATE THE HIGH WATER MARK STA MAv}XAD NOTMAX SEC SBC BUFAD STA ZCTR TYA SBC BUFAD+1 STA ZCTR+1 INC ZCTR BNE LENOK INC ZCTR+1 LENOK JSR DEBUG1 LDY BUFAw}D+1 LDA BUFAD CPY MINAD+1 ;AND IF IT SETS A NEW LOW ADDRESS LOADED BCC NEWMIN BNE NOTMIN CMP MINAD BCS NOTMIN ;UPDATEx} THE LOW WATER MARK NEWMIN CPY #$03 BCC NOTMIN STY MINAD+1 STA MINAD NOTMIN CPY #$07 BCC DONTMV CPY #$C0 ;SKIP THE INDIy}RECT BUFFER AND MOVE BCS DONTMV ;IF THE ADDR <0700 OR >BFFF ADC #LOW[BUFFER-$700] PHA TYA ADC #HIGH[BUFFER-$700] TAY z}PLA DONTMV STA BPTR STY BPTR+1 JSR DEBUG2 LDA #0 STA ILEN STA ILEN+1 ;READ ONE BYTE AT A TIME GETNB LDX #$10 JSR CIOV {} BPL STBYTE ;AND IF NO ERROR, STORE IT ABORT LDX #LOW[ABORTED] LDY #HIGH[ABORTED] JSR DMSG ;REAL I/O ERROR JMP ($000A) |};EXIT TO DOS ; STBYTE LDY BPTR BNE STBY0 LDY BPTR+1 ;TEST FOR BUFFER POINTER BEING STILL VALID CPY #$C0 BNE STBY0 STA S}}AVC BEQ STBY3 STBY0 LDY #0 STA (BPTR),Y ;ALL OK, STORE THE BYTE JUST READ STBY3 INC BPTR BNE STBT1 INC BPTR+1 STBT1 LDA Z~}CTR BNE STBT2 ;INCREMENT THE MEMORY POINTER DEC ZCTR+1 STBT2 DEC ZCTR LDA ZCTR ORA ZCTR+1 ;DECREMENT THE BYTE COUNTER }BNE GETNB ;IF STILL IN THE BLOCK, READ THE NEXT BYTE JMP RDNXTB ;ELSE, EXAMINE THE NEXT BLOCK ; MOVER LDA #12 ;DONE WITH }THE LOAD, STA ICMD LDX #$10 JSR CIOV ;CLOSE LOAD FILE JSR PSTR DB '(',0 LDA MINAD+1 JSR PHEX ;REPORT THE LOW AND HIG}H WATER MARKS LDA MINAD JSR PHEX JSR PSTR DB '-',0 LDA MAXAD+1 JSR PHEX LDA MAXAD JSR PHEX LDX #LOW[LOADED] LDY #HI}GH[LOADED] JSR DMSG RTS ;AND RETURN TO THE MAIN LINE CODE ; ; PROGRAM FILE (NEW FMS) ; DOSFIL DB 'D:MDOS.OBJ',$9B ; ; PRO}GRAM FILE (NEW UTILITY PROGRAM) ; DUPFIL DB 'D:MDUP.OBJ',$9B ; ; CONSOLE KEYBOARD/DISPLAY ; EC DB 'E:',$9B ; ; DISPLAY A MESS}AGE AND WAIT FOR "START" ; WFSTR JSR DMSG ;NESTED CALL TO DISPLAY THE MESSAGE LDA #8 STA $D01F WFSTRT LDA $D01F ;READ CON}SOLE SWITCHES AND #1 BNE WFSTRT ;WAIT UNTIL START IS DEPRESSED RTS ; ; DISPLAY A MESSAGE TO THE OPERATOR ; DMSG STX ZPTR } STY ZPTR+1 LDA #0 STA ZCTR MSGLP LDY ZCTR LDA (ZPTR),Y BEQ DXIT JSR BYTOUT INC ZCTR BNE MSGLP ; DXIT RTS ; CODE DB '0}123456789ABCDEF' ; ; DISPLAY A 4 DIGIT HEX NUMBER ON THE SCREEN ; PHEX PHA LSR A LSR A LSR A LSR A TAX LDA CODE,X JSR} BYTOUT PLA AND #$0F TAX LDA CODE,X ; BYTOUT LDX #11 STX ICMD-$10 LDX #0 STX ILEN-$10 STX ILEN-$10+1 JSR CIOV RTS ;} PSTR PLA STA ZPTR PLA STA ZPTR+1 PLOOP INC ZPTR BNE POUT INC ZPTR+1 POUT LDX #0 LDA (ZPTR,X) BEQ PEXIT JSR BYTOUT J}MP PLOOP ; PEXIT LDA ZPTR+1 PHA LDA ZPTR PHA RTS ; ; REPORT THE HIGH AND LOW BUFFER LIMITS ; DEBUG1 JSR PSTR DB '(',0 }LDA BUFAD+1 JSR PHEX LDA BUFAD JSR PHEX JSR PSTR DB '-',0 LDA BUFAD+3 JSR PHEX LDA BUFAD+2 JSR PHEX RTS ; DEBUG2 JS}R PSTR DB ')' DB $1E,$1E,$1E,$1E,$1E DB $1E,$1E,$1E,$1E,$1E DB $1E,0 RTS ; ; ROUTINE TO REINITIALIZE DOS 2.0 ; DOSINI L}DA $704 STA $00C LDA $704+1 STA $00C+1 JMP ($00C) ;==REINITIALIZE ENTIRE DOS/DUP ; ; MESSAGES TO OPERATOR ; SIGNON DC $}9B,$9B,' ' DC 'M','Y','D','O','S','3',' ','d','o','u','b','l','e' DC ' ','d','e','n','s','i','t','y' DC ' ','A','T','A','}R','I',' ','O','S',' ',$9B DB ' ' DC ' ',' ',' ',' ',' ',' ','s','y','s','t','e','m' DC ' ','d','i','s','k',' ','b','u','i}','l','d','e','r' DC ' ',' ',' ',' ',' ',' ',' ',$9B,$9B DB 0 ; MSG01 DB 'LOADING MDOS.OBJ',0 MSG02 DB 'LOADING MDUP.OBJ',0} LOADED DB $1E,$1E,$1E,$1E,$1E DB $1E,$1E,$1E,$1E,$1E DB $1E,$1E,$1E,$1E,$1E DB $1E,$1E,$1E,$1E,$1E DB $1E,$1E,'ED',$FE,$}9B,0 MSG03 DB 'Moving DOS/DUP into place',$9B,0 MSG04 DB 'PRESS ' DC 'S','T','A','R','T' DB ' TO INITIALIZE NEW DOS',$9B,0 }MSG05 DB 'PRESS ' DC 'S','T','A','R','T' DB ' TO ENTER NEW DOS.',$9B,0 ; NOFIL DB 'Cannot open Object File',$9B,0 NOHDR DB }'Invalid Header in Object File',$9B,0 ABORTED DB 'I/O Error, load aborted',$9B,0 ; ; BUFFER FOR PATCHING A RUNNING DOS ; MAX}AD DS 2 MINAD DS 2 SAVC DS 1 BUFAD DS 6 ;FOR ADDRESSES BUFFER DS START-$0700 ; ; EXECUTION FORCED, LOAD RUN ADDRESS ; ; ORG $}02E0 ; DW START ;run address ; END START R ADDRESSES BUFFER DS START-$0700 ; ; EXECUTION FORCED, LOAD RUN ADDRESS ; ; ORG $+MYDOS 4.51 -- Released June 14, 1989 MYDOS 4.51 restores some of the "features" of 4.3, including being written in Atari AMA }C syntax (that is, compatible with MADMAC and my own A65 assemblers). This seems more consistent than MAC/65. See the followi }ng list for the changed code. Like 4.50, it mostly fixes bugs in features that never worked right in the past. the changes ar }e very minor. Changes from 4.50 to 4.51 -- 1.Lock/Unlock work the way they used to. Query is the default. 2.A bug inser }ted into the program load code is corrected (some code that has to be resident was moved into the DUP overlay area). 3. }The code to work around I/O errors deleting the program file in most BASIC program "starter"s is re- inserted (inadvert }ently removed in 4.50). 4.Formatting of disks with bad sec- tors is reenabled (with warning). 5.Corrected code to copy DO }S.SYS from one diskette to another (this never really worked before). 6.The RAMdisk configuration code in- serted by Bo }b Puff was retained, but the old code (with specifiable I/O port) is restored for non- Axlon, non-XE compatible RAMdisk }s. 7.The correction to keep the VTOC of other disks from being corrupt- ed when I/O errors occurred while writing a VTO }C was worse than the problem (any I/O error scrambles all VTOCs with output files open). Perhaps the best fix is to ret }ry forever? Anyway, this is still a problem area. 8.And, of course, the assembler A65 is included. The executable code } in MYDOS 4.51 was all assembled using A65. Copying DOS.SYS -- we now . . . 1) load the 3 boot sectors into RAM from }the source disk. 2) copy the actual file, renaming it "diamond"OS.SYS on the destina- tion disk. 3) write the 3 boot se }ctors to the destination drive (updating the sector link mask, link location and sector size flag). 4) rename "diamo }nd"OS.SYS to DOS.SYS (updating the sector size flag and the starting sector number of DOS.SYS). To do (before 1990 }, at least): 1. Add script (batch file) support. 2. Enable BASIC if no cartridge is installed and the [B] command is i }ssued. Then, disable BASIC if the [L] or [N] commands are issued. Any volunteers? Enjoy, Charles Marslett Usenet: }chasm@killer.dallas.tx.us Compuserve: 73317,3662 June 16, 1989 issued. Any volunteers? Enjoy, Charles Marslett Usenet: @ TITLE 'LARGE DISK FMS' ; ; Copyright 1984, Charles Marslett, Wordmark Systems ; ; Permission is granted by the author for }any use whatsoever of this ; code, so long as this notice remains in the source code, and so ; long as the source to th}is routine, however modified or unmodified, ; is made available for a nominal cost. ; LIST C,G,I ; ; DISK I/O EQUATES ; }DKADDR = $31 ;SIO ADDRESS OF FIRST DISK DRIVE (D1:) TODK = $80 ;STATUS BYTE FOR A DATA TRANSFER TO THE DISK FROMDK = $40 ;STA}TUS BYTE FOR A DATA TRANSFER FROM THE DISK ; READ = 'R' ;SIO COMMAND EQUATE FOR READING A DISK WRITE = 'P' ;SIO COMMAND EQUAT}E FOR WRITING A DISK RDSTAT = 'S' ;SIO COMMAND EQUATE FOR READING THE DRIVE STATUS WRITEV = 'W' ;SIO COMMAND EQUATE FOR WRITI}NG A DISK with VERIFY FMTCMD = '!' ;SIO COMMAND TO FORMAT A DISKETTE ; LK128 = 125 ;LOCATION OF 128 BYTE SECTOR LINK LK256 = }253 ;LOCATION OF 256 BYTE SECTOR LINK ; WARMST = $0008 DOSVEC = $000A DOSINI = $000C ; ORG $0020 ICHIDZ DS 1 ICDNOZ DS 1 ICC}OMZ DS 1 ICSTAZ DS 1 ICBALZ DS 1 ICBAHZ DS 1 ICPTLZ DS 2 ICBLLZ DS 1 ICBLHZ DS 1 ICAX1Z DS 1 ICAX2Z DS 1 DS 2 CURFCB DS 1 DA}TBYT DS 1 ; ORG $0031 CHKSUM DS 1 BUFR DS 2 ; ORG $0043 FMSZPG DS 2 DIRDSP = FMSZPG DIRSEC = FMSZPG+1 CURFNO DS 1 FMSBPT DS} 2 TMP1 DS 1 TMP2 DS 1 ; ; DEFINITIONS FOR THE ATARI ROM EXECUTIVE ; DSKTIM = $0246 RUNADR = $02E0 INIADR = $02E2 MEMTOP = $}02E7 DVSTAT = $02EA ; ; SIO COMMAND BUFFER DEFINITION ; ORG $0300 DDEVIC DS 1 DUNIT DS 1 DCOMND DS 1 DSTATS DS 1 DBUFLO DS }1 DBUFHI DS 1 DTIMLO DS 2 DBYTLO DS 1 DBYTHI DS 1 DAUX1 DS 1 DAUX2 DS 1 ; ; I/O SYSTEM DEFINITIONS ; HATABS = $031A ;BASE O}F THE DYNAMIC HANDLER TABLE ; ; CIO COMMAND TABLE BASE DEFINITIONS (FOR IOCB $00) ; ORG $0340 ICHID DS 1 ICDNO DS 1 ICCOM D}S 1 ICSTA DS 1 ICBAL DS 1 ICBAH DS 1 ICPTL DS 1 ICPTH DS 1 ICBLL DS 1 ICBLH DS 1 ICAX1 DS 1 ICAX2 DS 1 ICSPR DS 4 ; ; CARTRI}DGE SUBSYSTEM DEFINITIONS ; CARINIT = $BFFE ;LOCATION OF INIT VECTOR CARTEST = $BFFC ;LOCATION OF FLAGS CARRUN = $BFFA ;LO}CATION OF RUN VECTOR ; ; 800XL MAP CONTROL ; MAPREG = $D301 ; ; OTHER I/O PORT DEFINITIONS ; NMIEN = $D40E ; ; ROM VECTORS} ; DSKINV = $E453 ;SINGLE DENSITY DISK I/O ENTRY POINT SIOV = $E459 ;SERIAL I/O O.S. ENTRY POINT ; INCLUDE D:MDOS1.ASM ;DA}TA AND CODE THAT REMAINS FIXED ; INCLUDE D:MDOS2.ASM ;FILE SYSTEM FUNCTIONS ; INCLUDE D:MDOS3.ASM ;INTERNAL DISK I/O ROUTIN}ES ; INCLUDE D:MDOS4.ASM ;UTILITY SUBROUTINES ; BOOTND END ;START DUP HERE! INCLUDE D:MDOS3.ASM ;INTERNAL DISK I/O ROUTINO;================================================= ;= MYDOS BOOT CODE == ;================================================}= ; ; DISK BOOT SECTORS (3) ; ORG $0700 ;DOS.BOOT LOADS AT 0700 BOOTFL DB 'M' ;INDICATE MYDOS 4.5 OR LATER BOOTL DB 3 ;NUMBE}R OF SECTORS IN THE BOOT BOOTAD DW BOOTFL ;ADDRESS OF BOOT CODE IN RAM BOOTIN DW INIT JMP INBOOT ;JUMP TO THE BOOT CONTINUAT}ION FILES DB 3 ;NUMBER OF FILES THAT MAY BE OPEN AT ONCE ;DRIVES = * ;USED TO BE BIT PATTERN FOR DRIVES RAMDKU DB $09 ;RAM DI}SK UNIT # ;BUFALC = * ;USED TO BE BUF. ALLOC. DIR. DEFAULT DB 1 ;DEFAULT UNIT NUMBER DOSEND DW BOOTND ;ADDRESS OF THE FIRST B}YTE OF FREE MEM. SECDAT DB 1 ;1=128 BYTE SECTOR/2=256 BYTE SECTOR DOSLOC DW 4 ;SECTOR ADDRESS OF DOS.SYS DLINK DB LK128 ;OFFS}ET TO THE SECTOR LINK FIELD DOSAD DW BASE ;ADDRESS TO LOAD DOS.SYS INTO ; INBOOT LDY DOSAD ;SET UP START OF DOS AS BUFFER ADD}RESS LDA DOSAD+1 JSR BTSET ;LOW ADDR IN Y, HIGH IN A ; LDA DOSLOC+1 LDY DOSLOC ;PUT DOS DISK ADDRESS INTO (A,Y) ; ; DOS.S}YS INPUT LOOP ; INITLP CLC ;CLEAR CY, 'DO A READ' LDX SECDAT ;GET CODE FOR SECTOR SIZE BEQ NODOS ;IF ZERO, NO DOS ON DISK!} JSR DKIO ;INVOKE DISK I/O ROUTINE BMI NODOS ;IF AN ERROR, RETURN NO-DOS ERROR LDY DLINK ;POINT TO LINK LDA (FMSZPG),Y ;C}HECK FOR NEXT LINK (10-BITS) ANDCD AND #$03 ;BEING ZERO, PHA ;SAVE UPPER BYTE OF ADDRESS INY ORA (FMSZPG),Y ;IF SO, LOADI}NG IS COMPLETE BEQ BOOTXT LDA (FMSZPG),Y ;ELSE, IT'S THE ADDRESS OF NEXT SECTOR PHA ;SAVE LOWER BYTE ON STACK JSR MVBUFR} ;THEN ADJUST THE BUFFER POINTER IN DCB PLA TAY ;RESTORE LOWER BYTE TO Y-REG PLA ;RECOVER UPPER BYTE OF DISK ADDRESS BC}C INITLP ;AND CONTINUE LOADING ; NODOS LDA #$C0 ;NO BOOT PROGRAM ERROR CODE DB $A0 ;SKIP SINGLE BYTE (LDY #) ; BOOTXT PLA DO}SXIT ASL A ;SET CARRY, CONVER CODE TO FINAL VALUE TAY ;PUT CODE INTO Y-REG RTS ;AND EXIT ; ; MOVE BUFFER POINTERS TO NEXT} AREA TO BE LOADED ; MVBUFR LDA DLINK CLC ADC FMSZPG ;ADD DLINK TO THE CURRENT BUFFER ADDRESS TAY ;LOW BYTE TO Y-REG LDA} FMSZPG+1 ADC #0 BTSET STY FMSZPG STA FMSZPG+1 BUFSET STY DBUFLO ;STORE LOW BYTE INTO DCB STA DBUFHI ;THEN UPPER BYTE RTS} ; ; PERFORM DISK READ(CY=0) OR WRITE (CY=1) ; DKIO STA DAUX2 ;STORE UPPER BYTE OF SECTOR ADDRESS STY DAUX1 ;THEN LOWER BYTE} DKIO2 LDY #3 LDA #READ BCC SETRTY ;IF CY=0, READ INTO RAM LDA WRCMDB ; SETRTY STY TMP1 ;SET NUMBER OF TRIES DKFME STA DCO}MND CLC LDA #WRITEV ;CLC AND CONSTANT FOR POKERS WRCMDB = *-1 STY DTIMLO LDA #128 ;ASSUME A 128-BYTE SECTOR SIZE DEX BE}Q STBUFL LDX DAUX2 ;SECTOR > 256? BNE SET256 LDX DAUX1 CPX #4 ;SECTOR > 3 BCC STBUFL ;IF NOT SET256 ASL A ;MAKE A 256 BY}TE SECTOR SIZE STBUFL STA DBYTLO ROL A STA DBYTHI LDY #DKADDR ;PUT DISK DEVICE CODE INTO DCB STY DDEVIC IORTRY DEC TMP1 }BMI DIOXIT LDX DCOMND INX TXA LDX #FROMDK ;ASSUME DATA ==> DISK AND #$06 BNE ISREAD ;IF NOT X0,X7,X8 OR XF, OK LDX #TO}DK ;ELSE, DATA ==> DISK ISREAD STX DSTATS ;RESTORE STATUS TO DCB JSR SIOV ;DO THE I/O OPERATIONS DEY BMI IORTRY ;IF NOT OK}, RETRY ; DIOXIT LDX CURFCB ;ELSE, LOAD FCB OFFSET AND STATUS INY TYA RTS ; ; FIXED RAM DEFINITIONS IN BOOT SECTORS ; DIUN}IT DS 1 ;UNIT NO. OF CURRENT DIRECTORY CDIREC DS 2 ;SECTOR NO. OF CURRENT DIRECTORY HOLFN DS 1 STATE DB $70 ;DUP loaded, MEM.}SAV inactive, Warmstart ; bit 7 -- MEM.SAV in use ; bit 6 -- DUP.SYS loaded ; bit 5 -- AUTORUN.SYS already run } ; bit 4 -- Initial BUILD active ; STKPSV DS 1 ;SAVED STACK POINTER ORG $07C0 ;MUST MATCH DUP LOCATION ; TRACKS DB 35,40},80,77 ;TRACKS IN EACH DISK FORMAT ; SECSIZ DB 0,0,0,0 ;BUFFER SIZE TABLE DB 0,0,0,0 ; DRVDEF DB $52,$52 ;DRIVE CONFIGURATI}ON TABLE: DB $D2,$D2 ;BIT 7=1 => NO DRIVE DB $D2,$D2 ;BIT 6=1 => ATARI 810 DRIVE DB $D2,$D2 ;BIT 5-4 IS (0=35, 1=40, ; } 2=80, 3=77 TRACKS(8") ;BIT 3=1 => DOUBLE DENSITY ;BIT 2-1 IS DRIVE STEP RATE ;BIT 0=1 => DOUBLE SIDED ; ; DOS.SYS }PROGRAM FOLLOWS ; DKEPT DW DKOPEN-1 DW DKCLOS-1 DW DKREAD-1 DW DKWRIT-1 DW DKSTAT-1 DW DKXIO-1 ; ORG $07E0 ; ; IDENTIFY} DRIVE TYPES ; INIT LDA #LOW[361] STA CDIREC LDA #HIGH[361] STA CDIREC+1 ; ; IDENTIFY DRIVE TYPES ; LDX #8 IDRVLP STX DU}NIT JSR ZERDVS ;ASSUME THE DRIVE IS NOT PRESENT LDA DRVDEF-1,X BMI NXTDRV ;IF NOT DECLARED, WE ARE DONE ; JSR JSTRD ;E}LSE, READ ITS STATUS BEQ NXTDRV ;IF ABSENT, GO ON TO THE NEXT ONE LDY #9 WOTCPY LDA WOTDCB,Y STA DDEVIC+2,Y DEY BPL WOT}CPY LDA DRVDEF-1,X CMP #$40 BCS NXTDRV ;IF NOT CONFIGURABLE, CONTINUE LDY SECSIZ-1,X JSR SETDRV ;TELL IT ABOUT MY CONF}IGURATION ; NXTDRV DEX ;STEP TO NEXT DRIVE NUMBER BNE IDRVLP ;IF MORE, LOOK AT THEM ; ; ZERO INITIALIZED MEMORY ; LDY #M}APBUF+7-CHGMAP TXA ;NOTE X=0 HERE ZERLP1 STA CHGMAP-1,Y DEY BNE ZERLP1 INC MAP2MOD ; ; DEFINE TOP OF FMS FOR USER PROGRA}M ; LDA DOSEND STA MEMTOP LDY DOSEND+1 ; ; ALLOCATE FILE SECTOR BUFFERS ; LDX #15 ;MAX OF 16 SECTOR BUFFERS DKBFLP CPX F}ILES ;EMPTY BUFFERS DONE? BCC ALCBUF DEC BUFFLG,X BMI DKBFSQ ALCBUF TYA STA SBTABU,X INY DKBFSQ DEX ;BUMP BUFFER COUN}TER BPL DKBFLP ;IF NOT CONTINUE LOOPING STY MEMTOP+1 ;DEFINE TOP OF MEMORY USED ; ; SET UP HANDLER VECTOR ; FNDHND INX IN}X INX LDA HATABS-2,X ;END OF THE HANDLER TABLE? BEQ NOHAND ;THEN INSTALL IT HERE CMP #$44 ;A 'D' ALREADY PRESENT? BNE }FNDHND ;NO, CONTINUE LOOKING, ELSE OVERWRITE IT ; NOHAND LDA #$44 ;WRITE AT END OF TABLE OR CURRENT "D" ENTRY STA HATABS-2},X LDA #LOW[DKEPT] ;STASH MYDOS ENTRY VECTOR STA HATABS-1,X LDA #HIGH[DKEPT] STA HATABS,X ;BUILD HANDLER VECTOR JMP DUPI}NV ;DONE, INITIALIZE DUP [overwritten by MDUP] ; ; DOS NON-ZERO PAGE RAM ALLOCATIONS ; CHGMAP DS 1 CURMAP DS 1 MAP2 DS 1 MAP}2MOD DS 1 LSTSEC DS 2 LSTIOCB DS 1 ; ; MYDOS FCB STRUCTURE (ALMOST THE SAME AS ATARI DOS 2.0) ; FCBFNO DS 1 FCBOTC DS 1 ;OPE}N TYPE CODE FCBFLG DS 1 MAXLEN DS 1 CURLEN DS 1 BUFNO DS 1 CURSEC DS 2 LNKSEC DS 2 SECCNT DS 2 DIRBAS DS 2 ;BASE ADDRESS OF C}UR. SECTOR SAVSEC DS 2 FCBLEN = 16 DS 7*FCBLEN ;SPACE FOR THE REMAINING 7 IOCBs ; BUFFLG DS 16 ;IF 0, BUFFER NOT IN USE SBTA}BU DS 16 ;UPPER BYTE OF THE SECTOR BUFFER ADDRESS MAPBUF DS 512 ;SPACE ALLOCATED FOR VTOC DIRBUF = MAPBUF ;SPACE ALLOCATED TO} READ DIRECTORIES FNAME DS 12 CURMP DS 1 ; BASE = * HDTAB DW 0,0,0,0 ;8 LOGICAL HARD DRIVES OF DW 0,0,0,0 ;UP TO 65535 SECTO}RS EACH ; ; ;NOTE: this table is referenced by DUP.SYS, and should not be moved! ; ; DOS CONFIGURATION CODE ; ; CONTROL BLOCK} TO BE WRITTEN TO A DRIVE TO CONFIGURE IT ; WOTDCB DB $4E,$40 DW DIRBUF,1 DW 12,4 ; ; THE CONFIGURATION CODE, FORCES A DRI}VE INTO THE APPROPRIATE CONFIGURATION ; SETDRV AND #$3F ;EXTRACT CONF. BITS STA TMP1 STY TMP2 JSR SIOV ;READ CURRENT CON}FIGURATION BMI JSTRD LDA TMP1 LDY TMP2 LSR A PHA ;SAVE REMAINING BITS AND #3 ;EXTRACT STEP RATE CODE STA DIRBUF+1 }LDA #0 STA DIRBUF+2 ROL A STA DIRBUF+4 ;STORE DOUBLE SIDED FLAG TYA ;GET DENSITY LSR A STA DIRBUF+6 ;STORE UPPER BYTE} OF SECTOR SIZE ROR A STA DIRBUF+7 ;THEN LOWER BYTE ROL A ASL A ASL A STA DIRBUF+5 PLA LSR A LSR A LSR A ;POSITION} TRACK COUNT FIELD TAY LDA TRACKS,Y ;GET NUMBER OF TRACKS STA DIRBUF AND #$04 ;SEE IF 77 TRACK 8 IN. PHA LSR A ORA DI}RBUF+5 ;MERGE D/DENSITY WITH 8 IN. FLAG STA DIRBUF+5 PLA ASL A ;CONVERT TO 0 OR 8 ADC #18 ;SECTOR COUNT = 18 OR 26 STA} DIRBUF+3 LDY DUNIT LDA HDTAB-1+8,Y BEQ TOSIOV STA DIRBUF+2 ;SIZE = SECTORS/TK LDA HDTAB-1,Y STA DIRBUF+3 ;LOW BYTE OF }SIZE LDA #1 STA DIRBUF ;ONE TRACK/DRIVE TOSIOV INC DCOMND ;CHANGE COMMAND TO WRITE LDA #$80 STA DSTATS ;SET DIRECTION }-> DISK JSR SIOV ;WRITE OPTION TABLE TO DRIVE ; JSTRD LDA #RDSTAT STA DCOMND JSR DSKINV LDX DUNIT TYA BMI ZERDVS LDA }DVSTAT ASL A ;SECTOR SIZE=256? ASL A ASL A LDA #1 ADC #0 SETSIZ STA SECSIZ-1,X RTS ; ZERDVS LDA #0 BEQ SETSIZ ;ALWAY}S BRANCHES! ; ; DOS RAMDISK CODE (moved here starting with version 4.5) ; ; RAM DISK I/O HANDLER (POS. IND. CODE) ; MAPAGE D}B $E3,$E7,$EB,$EF DB $83,$87,$8B,$8F DB $C3,$C7,$CB,$CF DB $A3,$A7,$AB,$AF ; DB $93,$97,$9B,$9F DB $D3,$D7,$DB,$DF DB $}B3,$B7,$BB,$BF DB $F3,$F7,$FB,$FF ; DB $E3,$E7,$EB,$EF DB $83,$87,$8B,$8F DB $C3,$C7,$CB,$CF DB $A3,$A7,$AB,$AF ; DB $9}3,$97,$9B,$9F DB $D3,$D7,$DB,$DF DB $B3,$B7,$BB,$BF DB $F3,$F7,$FB,$FF ; VALSEC PHA TYA ORA #$80 LSR A STA BUFR+1 SEI} ;DISABLE INT-S LDA #0 STA NMIEN ;DISABLE NMI-S ROR A STA BUFR PLA TAY LDA MAPREG ORA #$1C STA CHKSUM ORA #$7C AN}D MAPAGE,Y STA MAPREG ;SELECT RAMDISK DATA PAGE ; LDA DBUFLO ;USER BUFFER ADDRESS GOES HERE STA BUFR+2 LDA DBUFLO+1 STA }BUFR+3 LDY #0 PLP BCC RREADL ;CY=0 IF READ RWRITL LDA (BUFR+2),Y STA (BUFR),Y INY BPL RWRITL BMI RIOX ; RDKIO STY DAUX}1 ;*** FOR FORMAT CODE *** CPY #$80 ROL A CMP #4 RDKLMT = *-1 ;NUMBER OF 16K PAGES IN RAMDISK BCC VALSEC ;CALCULATE MEM. }ADDR. PLP LDA #139 BMI RERROR ; RREADL LDA (BUFR),Y STA (BUFR+2),Y INY BPL RREADL ; RIOX LDA CHKSUM ;FORCE REAL RAM PAG}E STA MAPREG ;BEFORE EXITING LDA #$C0 STA NMIEN ;RE-ENABLE NMI CLI ;ENABLE INTERRUPTS LDA #1 ;RETURN '1' IN Y-REG RERRO}R STA DSTATS ;AND IN STATUS BYTE LDX CURFCB ;RESTORE FCB ADDR TAY RTS ;THEN EXIT ; STEPBP LDA DBUFLO EOR #$80 STA DBUFL}O BMI TSTEOD INC DBUFHI ; TSTEOD LDY DAUX1 RTS ORE FCB ADDR TAY RTS ;THEN EXIT ; STEPBP LDA DBUFLO EOR #$80 STA DBUFL2; ; DISK OPEN ROUTINE ; DKOPEN JSR WBITMP ;Fix nasty bug! [Bob Puff] JSR SETUP ;SET UP BUF PTRS, ETC. JSR GETFNM ;GET D }RIVE ID OR FILE NAME FROM BUFFER LDA ICAX1Z ;GET TYPE OF OPEN FROM IOCB STA FCBOTC,X AND #$02 ;TEST DIRECTORY READ FLAG  } BEQ DKOPN1 JMP LSTDIR ;IF SET, GO HANDLE DIRECTORY FORMATTING ; DKOPN1 STA SAVSEC,X STA SAVSEC+1,X ;CLEAR SAVSEC JSR SFD }IR PHP ;SAVE STATUS RETURNED BCS OPNEW LDA #$10 ;MAKE SURE THIS IS NOT A DIRECTORY JSR GETFLAG BNE DIROPN ;IF A DIRE }CTORY, GO HANDLE IT SEPERATELY OPNEW LDY ICAX1Z CPY #8 BEQ OPNOP ;IF OPEN FOR OUTPUT CPY #4 BEQ OPNIN ;IF OPEN FOR INPU }T CPY #12 BEQ OPNUP ;IF OPEN FOR READ/WRITE (UPDATE) CPY #9 BEQ OPNAP ;IF OPEN FOR OUTPUT/APPENDED DIROPN JMP ERRCMD ;}IF NONE OF THE ABOVE, IT IS AN ERROR! ; OPNAP PLP ;OPEN APPEND BCS OPNCR0 JSR TSTLOK JSR INITYP ;READ ALL THE SECTORS IN }THE FILE LDA DIRBUF+1,Y STA SECCNT,X LDA DIRBUF+2,Y STA SECCNT+1,X APPRD JSR RDNXTS BCC APPRD ;IF NOT EOF, READ ANOTHER } LDA MAXLEN,X JSR LENSET ;SET LENGTHS FOR OUTPUT LDA SECCNT,X BNE SGLDEC DEC SECCNT+1,X SGLDEC DEC SECCNT,X ;ALLOW FOR SE}CTOR REWRITTEN JMP OPOUTX ; OPNUP PLP ;OPEN UPDATE (OUTPUT) BCS OPNER1 JSR TSTLOK OPNOWR JSR INSTRT JMP DONE ; OPNIN PLP} ;OPEN INPUT BCC OPNOWR OPNER1 LDA #170 ;FILE NOT FOUND BMI EROXIT ; OPNOP PLP ;OPEN (NORMAL) OUTPUT BCS OPNCR JSR REMO}VE JMP GET1ST ; OPNCR0 DEC FCBOTC,X OPNCR LDA HOLFN STA CURFNO BMI OPDIRF GET1ST JSR ALLOC ; LDA ICAX2Z ;IF OUTPUT, TYPE }OF FILE AND #$24 ;SAVE LOCKED & FORMAT BITS (with 4.5, DOS I no-more) EOR #$43 ;MERGE IN DEFAULT CODE (DOS II, UNLOCKED) L}DY MAPBUF ;WHICH TYPE DISK? CPY #3 ;IF >2 THEN MYDOS BCC LLINKS ORA #$04 ; LLINKS PHA JSR RDCFNO ;SELECT PROPER SECTOR IN} DIRECTORY SEC JSR ENTNAME ;ENTER NAME INTO IT LDA LNKSEC+1,X STA DIRBUF+4,Y LDA LNKSEC,X STA DIRBUF+3,Y PLA JSR SAV}FLAG JSR INITYP JSR TONXT OPOUTX LDA #$80 STA FCBFLG,X JSR TSTDOS ;FILE NAME = DOS.SYS? BNE JDONE LDY CURSEC,X LDA CU}RSEC+1,X JSR SETDOS ;IF SO, UPDATE BOOT SECTORS ; LDA DOSAD STA FMSZPG LDA DOSAD+1 STA FMSZPG+1 BNE OWTDOS ;NOTE: DOS} CANNOT START ON ZERO-PAGE ; OPDIRF LDA #169 EROXIT JMP AEXIT ; LWTDOS JSR WRNXTS ;AUTOMATICALLY WRITE DOS.SYS OUT OWTDOS LD}Y #0 ;IF WE OPEN "DOS.SYS" FOR A WRITE CDOSBF LDA (FMSZPG),Y ;(THIS IS BECAUSE DOS 2.0 WOULD BLOW STA (FMSBPT),Y ; ITSELF A}WAY IF A REAL WRITE FROM THE INY ; DOS AREA WAS ATTEMPTED, AND WE HAVE CPY DLINK ; TO REMAIN COMPATIBLE). BCC CDOSBF T}YA STA CURLEN,X JSR MVBUFR CPY DOSEND SBC DOSEND+1 BCC LWTDOS JDONE JMP DONE ; ; READ DATA FROM A FILE ; DKREAD JSR SETU}P ;SETUP BUFFER POINTERS, ETC. LDA FCBOTC,X AND #$02 ;TEST THE DIRECTORY I/O FLAG BEQ RDFILE JMP DIRRD ;JUMP IF THE SP}ECIAL CASE OF A DIRECTORY READ ; RDFILE LDA CURLEN,X CMP MAXLEN,X BCC RDSGBT ;IF NOT AT SECTOR BOUND., READ A BYTE AT A TI}ME BCS RDASNT ;ELSE, CHECK FOR READ MODE AND BUFFER SIZE ; RDASLP LDA ICCOMZ AND #$02 BEQ RDSGBT ;IF NOT BINARY I/O READ } A BYTE AT A TIME LDY DLINK DEY RDSCLP LDA (FMSBPT),Y ;SIMULATED BURST I/O (with unrolled loop) STA (ICBALZ),Y DEY LDA (!}FMSBPT),Y STA (ICBALZ),Y DEY LDA (FMSBPT),Y STA (ICBALZ),Y DEY LDA (FMSBPT),Y STA (ICBALZ),Y DEY BNE RDSCLP LDA (FM"}SBPT),Y ;NUM OF DATA BYTES IS MULTIPLE OF 4 + 1 STA (ICBALZ),Y JSR BUFADJ ;ADJUST BUFFER PTR BY 125 OR 253 RDASNT JSR RDNX#}TS ;READ IN THE NEXT SECTOR BCS RETEOF ;REPORT EOF/ERROR IF NECESSARY LDA ICBLLZ+1 BNE RDASLP ;AND REPEAT THE LOOP IF >$} 256 BYTES LEFT ; RDSGBT TAY LDA (FMSBPT),Y ;FETCH A DATA BYTE FROM THE BUFFER STA DATBYT ;AND RETURN IT TO CIO INY TYA %} STA CURLEN,X ;BUMP CURRENT BUFFER LENGTH EOR MAXLEN,X ORA LNKSEC,X ORA LNKSEC+1,X ;TEST FOR THE LAST BYTE OF THE FILE BN&}E JDONE LDA #3 ;IF IT IS, REPORT THIS IS THE LAST BYTE DB $2C ; RETEOF LDA #136 ;RETURN END OF FILE STATUS JMP AEXIT ; ;'} WRITE DATA TO A FILE ; DKWRIT STA DATBYT ;SAVE THE DATA BYTE (IF IT IS IN ACC) LDY ICDNO,X STY ICDNOZ ;INSURE ICDNOZ IS (}SET UP (BASIC DOES NOT!) JSR SETUPW LDA FCBOTC,X AND #$08 BEQ CANTWR ;ERROR OUT IF ILLEGAL TO WRITE (BASIC AGAIN!) LDA )}CURLEN,X TAY CMP MAXLEN,X BCC SKBURST ;SKIP AROUND IF NOT THE END OF THE SECTOR WRASLP JSR WRNXTS ;WRITE A SECTOR OF DA*}TA BCS RETEOF ;ERROR OUT IF NO MORE DISK SPACE LDY STKPSV LDA $0102,Y CMP #$C0 ;IF FROM BASIC (RETURN ADDRESS < $C000) +} BCC BASWRT ;PASS SINGLE BYTES LDA FCBOTC,X ;Fix bug in open/update vs. burst I/O AND #$04 ;[Bob Puff, again!] BNE BASWR,}T LDA ICCOMZ ;IF RECORD I/O, PASS SINGLE BYTES ALSO AND #$02 BEQ BASWRT LDY ICBLLZ+1 ;AND IF THE BUFFER HOLDS FEWER THAN-} 256 BYTES BEQ BASWRT ;PASS SINGLE BYTES AS WELL LDY MAXLEN,X DEY WRSCLP LDA (ICBALZ),Y ;ELSE, DO SIMULATED BURST I/O ST.}A (FMSBPT),Y DEY LDA (ICBALZ),Y STA (FMSBPT),Y ;BUT ONLY UNROLL 2 ENTRIES FOR WRITES! DEY ;(WE GOT VERY LITTLE RAM TO W/}ASTE!) BNE WRSCLP LDA (ICBALZ),Y STA (FMSBPT),Y JSR BUFADJ LDA (ICBALZ),Y STA DATBYT JMP WRASLP ; BASWRT LDY #0 SKBURS0}T LDA DATBYT INC CURLEN,X STA (FMSBPT),Y LDA #$40 ORA FCBFLG,X ;FOR UPDATE MODE, SAY THE SECTOR WAS MODIFIED STA FCBFLG,1}X BNE TODONE ;BRANCH ALWAYS! ; CANTWR JMP ERRCMD ; BUFADJ CLC LDA MAXLEN,X STA CURLEN,X ADC ICBALZ STA ICBALZ BCC RBAO2}K INC ICBALZ+1 RBAOK SEC LDA ICBLLZ SBC MAXLEN,X STA ICBLLZ BCS RBLOK DEC ICBLLZ+1 RBLOK RTS ; ; RETURN FILE STATUS ; D3}KSTAT JSR SETUP ;SET UP RETURN ADDRESS, ETC. JSR LFFILE ;FIND IF FILE IS THERE, ETC. JSR TSTLOK ;IS IT LOCKED? TODONE JM4}P DONE ;RETURN TO CALLER ; ; CLOSE FILE (WRITING ANY PENDING SECTOR) ; DKCLOS JSR SETUP LDA FCBOTC,X AND #$08 ;OUTPUT ALL5}OWED? BEQ CLROTC ;IF NOT, JUST EXIT ROL FCBFLG,X BCC CKFLSC JSR REWRIT ;REWRITE THE LAST SECTOR JSR RRDIR LDA SECCNT,6}X LDY DIRDSP STA DIRBUF+1,Y LDA SECCNT+1,X STA DIRBUF+2,Y LDA DIRBUF,Y AND #$FE ;NOT OPEN FOR OUTPUT ANY MORE JSR SAV7}FLAG LDA SAVSEC,X ORA SAVSEC+1,X BEQ CLROTC CPX LSTIOCB BEQ FAPPD JSR INITYP ;READ ALL THE SECTORS AGAIN APPLP JSR RDNX8}TS BCC APPLP ;NOT EOF YET BCS TIELNK FAPPD LDA LSTSEC STA CURSEC,X LDA LSTSEC+1 STA CURSEC+1,X TIELNK CLC JSR RWDISK L9}DA DLINK STA CURLEN,X LDA SAVSEC,X LDY SAVSEC+1,X JSR SAVLNK CLROTE BPL CLROTC LDA #163 ;FAILURE IS A SYSTEM ERROR JMP:} AEXIT CLROTC LDA #$FF STA ICHID,X LDA #0 STA FCBOTC,X JMP FREDON ; CKFLSC ROL FCBFLG,X BCC CLROTC JSR WRDISK JMP CLRO;}TE ; INITYP LDA #$06 JSR GETFLAG LSR A ROR A ROR A ROR A ORA FCBOTC,X STA FCBOTC,X LDA DIRBUF+3,Y STA LNKSEC,X LDA <}DIRBUF+4,Y STA LNKSEC+1,X LDA CURFNO STA FCBFNO,X LDA #0 STA FCBFLG,X STA CURLEN,X STA SECCNT,X STA SECCNT+1,X RTS ;=} ; DOS XIO ROUTINES ; ; Sorry about the lack of comments in some parts of this file, ; I just never had to figure this co>}de out after I wrote it (:-)! ; NODIRF LDA #176 ;FILE NOT A DIRECTORY JMP AEXIT ; PIKDIR LDY #0 LDA #':' FDVND INY CMP (I?}CBALZ),Y BNE FDVND INY LDA (ICBALZ),Y CMP #'@' BCC SETRDIR CMP #'Z'+1 BCC GFNDIR CMP #'_' BCC SETRDIR CMP #'z'+1 B@}CS SETRDIR GFNDIR JSR LFFILE ;FIND NEW DEFAULT DIRECTORY JSR INITYP JSR TONXDR BEQ NODIRF ;IF NOT A DIRECTORY LDA DIRBAA}S+1,X TAY LDA DIRBAS,X SAVDEF STY CDIREC+1 ;UPDATE ADDRESS OF DIR. STA CDIREC LDA ICDNOZ STA DEFAULT ;UPDATE UNIT NUMBEB}R BPL TOFDN ; SETRDIR LDA #LOW[361] LDY #HIGH[361] BPL SAVDEF ; RENAME JSR LFFILE ;GET OLD NAME, DRIVE, VALIDATE LDY #11C} STEMPL LDA FNAME-1,Y STA MAPBUF+256,Y DEY BNE STEMPL RNLOOP JSR TSTLOK ;CANNOT RENAME IF LOCKED JSR TDDOS ;TEST FOR DOD}S GONE! LDY TMP2 JSR GETNAM ;GET NEW NAME CLC JSR ENTNAME ;OVERWRITE NAME IN DIR. JSR WDIRBK ;REWRITE DIRECTORY TO DIE}SK ; JSR TSTDOS ;NEW NAME DOS.SYS? BNE REPLDS ;NO, LOOK AT NEXT LDY DIRDSP LDA DIRBUF+4,Y ;SAVE FILE LOCATION ON THE SF}TACK PHA LDA DIRBUF+3,Y PHA ; ;;; JSR SYSSET ;Use the MAP buffer [IS THIS NECESSARY???] ; CLC ; == READ LDX #1 ; == G}SECTOR SIZE CODE (1=128, 2=256) LDA #0 LDY #1 ; == SECTOR #1 JSR DKIO ;Read it ; LDA SECDAT STA MAPBUF+SECDAT-$0700 PH}LA STA MAPBUF+DOSLOC-$0700 PLA STA MAPBUF+DOSLOC+1-$0700 ; ;;; LDA #$00 ;[AND IS THIS REALLY NECESSARY???] ;;; STA MAPBUFI}+STATE-$0700 ; SEC ; == WRITE LDX #1 ; == SECTOR SIZE CODE (1=128, 2=256) JSR DKIO2 ;Write it (same sector as I read bJ}efore) ; LDA #$FF ;Then make sure we reread the directory buffer STA DIUNIT ; REPLDS LDY #11 RTEMPL LDA MAPBUF+256,Y STA K}FNAME-1,Y DEY BNE RTEMPL JSR CSFDIR ;TO RENAME BCC RNLOOP TOFDN JMP FREDON ; DELETE JSR LFFILE DELLP JSR REMOVE ;FLUSH L}THE SECTORS JSR RRDIR ;REREAD DIRECTORY BLOCK JSR TDDOS ;DOS.SYS DELETED? LDA #$80 JSR SAVFLAG ;REWRITE DIRECTORY BLOCM}K JSR CSFDIR BCC DELLP ;IF ANOTHER FOUND, BCS TOFDN ;ELSE, WRAP UP AND EXIT ; REMOVE JSR TSTLOK ;ONCE HAD 'OPVTOC' CALLN} FIRST JSR INITYP JSR TONXDR BNE DELDIR JSR CHASE ; FREELP JSR FREE JSR RDNXTS BCC FREELP RTS ; INVDEL LDA #175 ;DIREO}CTORY NOT DELETABLE JMP AEXIT ; LOCK LDA #$20 DB $2C ;BIT ABS (SKIP 2 BYTES) ; UNLOCK LDA #$00 STA DATBYT JSR LFFILE ;FP}IND FILE AND VERIFY WRITABLE LKULKL LDA #$DF ;STRIP OFF OLD BIT 5 JSR GETFLAG ORA DATBYT ;AND REPLACE WITH NEW JSR SAVFLQ}AG JSR CSFDIR BCC LKULKL BCS TOFDN ; DELDIR LDY #-11 LDA #'?' DELSET STA FNAME+11-256,Y INY BNE DELSET JSR SFDIR BCC R}INVDEL ; LDA #8 STA DATBYT JSR TONXT DELDRL JSR FREE JSR INCCSEC DEC DATBYT BNE DELDRL JMP GETFNM ; POINT LDY FCBFLG,XS} BMI ERRCMD ; LDA ICSPR+1,X CMP CURSEC+1,X BNE PNTREAD LDA ICSPR,X CMP CURSEC,X BEQ PNTSME PNTREAD TYA BEQ PNTCLN ;IT}F SECTOR UNMODIFIED JSR WRDISK LDA #0 STA FCBFLG,X PNTCLN LDA ICSPR+1,X STA LNKSEC+1,X LDA ICSPR,X STA LNKSEC,X JSR CHU}ASE ;READ SECTOR POINTED TO BCS BADPNT ; PNTSME LDA ICSPR+2,X CMP MAXLEN,X BCS PNTEQL PNTLST STA CURLEN,X JMP DONE ; PNTV}EQL BEQ PNTLST ;IF POINTING AT LAST BYTE BADPNT LDA #166 ;INVALID POINT LOCATION DB $AE ; ERRCMD LDA #168 ;INVALID IOCB PW}ARAMETER JMP AEXIT ; NOTE LDA CURSEC,X STA ICSPR,X LDA CURSEC+1,X STA ICSPR+1,X LDA CURLEN,X STA ICSPR+2,X JMP DONE ; X}DKXIO JSR SETUP LDA ICCOMZ ;GET COMMAND BYTE CMP #254 BEQ FORMAT CMP #43 ;ADD "MKDIR" CODE FOR SpartaDOS(?) [Bob Puff] Y} BCS ERRCMD ;IF INVALID COMMAND SBC #32-1 BCC ERRCMD TAY LDA VECTBH,Y PHA LDA VECTBL,Y PHA RTS ;VECTOR TO PROPER RZ}OUTINE ; VECTBH DB HIGH[RENAME-1],HIGH[DELETE-1] DB HIGH[MKDIR-1],HIGH[LOCK-1] DB HIGH[UNLOCK-1],HIGH[POINT-1] DB HIGH[NOT[}E-1],HIGH[DKLOAD-1] DB HIGH[ERRCMD-1],HIGH[PIKDIR-1] DB HIGH[MKDIR-1] ;extra vector to MKDIR [Bob Puff] ; VECTBL DB LOW[REN\}AME-1],LOW[DELETE-1] DB LOW[MKDIR-1],LOW[LOCK-1] DB LOW[UNLOCK-1],LOW[POINT-1] DB LOW[NOTE-1],LOW[DKLOAD-1] DB LOW[ERRCMD]}-1],LOW[PIKDIR-1] DB LOW[MKDIR-1] ; ; DOS FORMAT ROUTINES ; FORMAT JSR WBITMP ;WRITE OUT ANY PENDING VTOC SECTORS ; ldy #9^} ;Force format to match current density WOTCP2 lda WOTDCB,y ;set up DCB for specified density [Bob Puff] sta DDEVIC+2,y de_}y bpl WOTCP2 ldx ICDNOZ cpx RAMDKU beq WOTRAM ;don't do it for RAMdisks ; ldy SECSIZ-1,x lda DRVDEF-1,x jsr SETDRV `} ;set density WOTRAM ldx CURFCB ;restore X reg ; LDY #0 TYA ;THEN INITIALIZE NEW BIT MAP (VTOC) CLRMAP STA MAPBUF,Y STa}A MAPBUF+256,Y INY BNE CLRMAP ; LDA #2 STA MAPBUF ;start out as a DOS 2.0 disk LDA #$FF STA (FMSBPT),Y INY STA (FMSBb}PT),Y ;PRESUME NO BAD SECTORS IF BUFFER IS UNMODIFIED LDY ICDNOZ CPY RAMDKU BEQ RAMFMT ;IF RAMDISK, SKIP EVERYTHING LDA c}FMSBPT+1 LDY FMSBPT JSR BUFSET ;SET UP BUFFER POINTER FOR SIO CALL LDX #1 STX TMP1 ;ALLOW ONE TRY ONLY LDA #$22 ;PRESd}UME 1050 D/D FORMAT NEEDED LDY ICAX2Z ;GET AUX2 BYTE BMI FMTOK ;MINUS --> NO FORMAT REQUIRED BNE NMLFMT ;AUX2 NONZERO, e}NORMAL FORMAT WITH SIZE DEFINED LDY ICAX1Z ;(AUX2,AUX1) = 1? DEY BEQ FT1050 ;YES, FORMAT WITH A $22 COMMAND ; NMLFMT ldxf} DUNIT lda SECSIZ-1,X ;PUT SECTOR SIZE CODE (1 OR 2) INTO X tax lda #FMTCMD ;AUX IS 0, must not be 1050 d/d FT1050 STA DAg}UX1 ;MAKE SURE WE SECTOR > 3 LDY DSKTIM ;DISK TIMEOUT VALUE (RETURNED IN STATUS) JSR DKFME ;ENTER DKIO AT FORMAT ENTRY q}B%DOS SYSB*)DUP SYSBDSBUILD ASMBCHANGES BMDOS ASMBJMDOS1 ASMBMDOS2 ASMBaMDOS3 ASMB. MDOS4 ASMB:MDUP ASMBWMDUP1 ASMB$sMDUP2 ASMB6MDUP3 ASM0MDUP4 ASMMDUP5 ASM4MDUP6 ASMVGMDUP7 ASM'READ ME BPL FMTOK ;Accepting 144 errors here removed [Bob Puff] JMP AEXIT ;RETURN ERROR CODE IF ANY OCCURRED ; RAMFMT STA CURSEC,Xr} ;STUFF PROPER NUMBER OF SECTORS INTO CURSEC CLC ;(256-BYTE PAGES * 2 SINCE SECTOR SIZE IS 128) ADC RDKLMT LSR A ROR CUs}RSEC,X BNE NOTDEF ;FAIL IF NOT 256 SECTORS OR MORE (need 370) ; ; SUCCESSFUL FORMAT, CREATE VTOC AND EMPTY DIRECTORY ; FMTOt}K ;Bob Puff disabled the marginal format code ; ldy #0 ;check for a bad format ; lda (FMSBPT),y ; and (FMSBPT),y ;first u}two bytes $FF? ; cmp #$FF ; beq FMTOK2 ;yep, continue ; lda #173 ;otherwise format error ; bne FMEXIT ; FMTOK2 JSR INVUNITv} ;Can we do this (asks Bob Puff) JSR DELDOS LDA ICAX1Z STA CURSEC,X LDA ICAX2Z AND #$7F ;DISK MUST HAVE 256 SECTORS Bw}NE NOTDEF ;IF SIZE SPECIFIED, USE IT LDY ICDNOZ LDA HDTAB-1,Y ;IF NOT AND THIS IS A HARD DISK STA CURSEC,X ;USE THE SYSTEx}M DEFINED SIZE LDA HDTAB+8-1,Y BNE NOTDEF BIT DVSTAT ;1050 DRIVE? BPL FIGSIZ ;NO, FIGURE SIZE THEN LDA #LOW[1040] ;YESy}, FORCE TO 1040 SECTORS STA CURSEC,X LDA #HIGH[1040] BNE NOTDEF ; FIGSIZ LDA DRVDEF-1,Y AND #$31 ;EXTRACT TRACK COUNT FLz}AGS LSR A PHP LSR A LSR A TAY LDA NOSECS,Y ;AND USE DRIVE DEFAULT SECTOR COUNT STA CURSEC,X LDA NOSECS+1,Y PLP BCC {}NOTDEF ;IF NOT DOUBLE SIDED, THIS IS IT ASL CURSEC,X ROL A ;ELSE, DOUBLE IT ; NOTDEF STA CURSEC+1,X CMP #4 ;NEED 16 BIT|} LINKS? BCC SHORTS ;NO, SHORT FORMAT OK INC MAPBUF ;YES, FORCE LONG FORMAT (DOS3) SHORTS JSR FNDBIT ;FIND LAST BIT MAP S}}ECTOR LDA TMP2 BNE GT246 ;IF PAST 256TH MAP BYTE BIT DLINK ;SINGLE DENSITY? BMI FDBDEN CPY #0 BPL FDBDEN GT246 STA MA~}P2 CLC ADC #3 STA MAPBUF FDBDEN LDA #HIGH[-9] STA MAPBUF+4 LDA #LOW[-9] STA MAPBUF+3 ;START WITH 9 FREE SECTORS UN-FREE}! FLOOP JSR FMTFRE JSR DECCSEC CMP #4 ;BOOT SECTORS YET? BNE FLOOP ;IF NOT, CONTINUE DEALLOCATING LDA CURSEC+1,X BNE F}LOOP ; ; ALLOCATE BAD SECTORS ; [Bob Puff replaced this with code to set FMSBPT to 1, since he ; disallows bad sectors] ; L}DY #0 CLRBDLP LDA (FMSBPT),Y STA CURSEC,X INY LDA (FMSBPT),Y STA CURSEC+1,X INY AND CURSEC,X CMP #$FF CLC BEQ MAPDON}E STY TMP1 JSR DECCNT JSR FNDLBIT EOR #$FF BCC CLRBD1 AND MAPBUF+256,Y STA MAPBUF+256,Y BCS CLRBD2 CLRBD1 AND MAPBUF,}Y STA MAPBUF,Y CLRBD2 LDY TMP1 BNE CLRBDLP SEC LDY #173*2-256 ;NO $FFFF => BAD FORMAT MAPDONE TYA ROR A STA FMSBPT ;PO}SITIVE VALUE = NUMBER OF BAD SECTORS ; ; [End of code that can be optionally deleted] ; LDA #$00 STA MAPBUF+55 LDA #$7F S}TA MAPBUF+56 LDY #44 ;START ALLOC. OF VTOC HERE LDA MAPBUF SEC SBC #2 ;GET NUMBER OF SECTORS BIT DLINK ;(SINGLE DENSI}TY?) BMI MPNSD ;IF NOT, M-3 ASL A ;IF SO, M*2-5 MPNSD TAX DEX ;MOVE COUNT TO X ; ALCMPL LDA #$FF ALCMAP DEX BMI SMBSI}Z PHA JSR DECCNT PLA ASL A BNE ALCMAP STA MAPBUF+10,Y DEY BPL ALCMPL ;BRANCH ALWAYS! ; SMBSIZ STA MAPBUF+10,Y LDA M}APBUF+3 ;MARK EMPTY SIZE, TOO STA MAPBUF+1 LDA MAPBUF+4 STA MAPBUF+2 JSR FMTMAP ;WRITE MAP TO DISK ; ; CREATE AN EMPTY }DIRECTORY ; LDA #LOW[361] LDY #HIGH[361] CLRDIR JSR SETDIR ;RESET THE DIRECTORY BASE SECTOR TYA CLRDLP STA DIRBUF,Y ;ZERO} THE DIRECTORY BUFFER INY BNE CLRDLP ; LDA #7 STA DIRSEC CLRDL2 JSR WDIRBK ;THEN WRITE ALL 8 SECTORS OUT DEC DIRSEC BP}L CLRDL2 LDY BUFNO,X LDA #0 STA BUFNO,X STA BUFFLG-1,Y ;FORMAT DONE, FREE THE INTERNAL BUFFER LDA FMSBPT JMP AEXIT ; NO}SECS DW 35*18,40*18,80*18,77*26 ; SETDIR STA DIRBAS,X TYA STA DIRBAS+1,X LDY #0 RTS ; ; DOS BINARY LOAD CODE (LOAD AND OP}TIONALLY EXECUTE A PROGRAM) ; DKLOAD LDA ICAX1Z STA ICPTLZ ;SAVE PROGRAM NAME BUFFER POINTER CMP #$08 BCS TOERRC ;IF WRI}TE, REPORT ERROR ; LDA #LOW[TORTS] STA RUNADR LDA #HIGH[TORTS] ;ASSUME RUNN ADDRESS IS ABSENT STA RUNADR+1 LDA #4 STA I}CAX1Z LDA ICHID,X ;IOCB OPEN? BPL CCFILE JSR DKOPEN ;IF NOT, OPEN IT BMI DKLERV JSR WDREAD ;READ ONE WORD OF THE HEAD}ER BEQ CCFILE LDY #180 ;NO $FFFF, HEADER ERROR CODE BMI DKLERV ; TOERRC LDY #168 ;INVALID IOCB RTS ; GETTXT LDA #LOW[TO}RTS] STA INIADR LDA #HIGH[TORTS] ;FOR EACH SEGMENT, RECLEAR THE INIT VECTOR STA INIADR+1 TXTLP JSR DKREAD DKLERV BMI DKLER}R LDY #0 STA (ICBALZ),Y INC ICBALZ BNE DECLEN INC ICBAHZ DECLEN LDA ICBLLZ BNE DECLOW DEC ICBLHZ DECLOW DEC ICBLLZ BN}E TXTLP LDA ICBLHZ BNE TXTLP LDA ICBAHZ CMP #HIGH[INIADR] BNE CCFILE ; LDA ICPTLZ ;IF NO INITS, LSR A BCS CCFILE ;S}KIP TO NEXT PAGE TXA ;ELSE SAVE IOCB PHA LDY #256-12 CPSICB LDA ICHIDZ-256+12,Y STA ICHID,X ;SAVE THE 12-BYTE IOCB ENT}RY INX INY BNE CPSICB PLA TAX PHA JSR DOINIT ;AND CALL INIT FUNCTION PLA TAX PHA LDY #256-12 CPRICB LDA ICHID,X };THEN RESTORE THE 12-BYTE IOCB STA ICHIDZ-256+12,Y INX INY BNE CPRICB PLA TAX ; CCFILE JSR WDREAD ;READ THE SEGMENT ST}ART ADDRESS BEQ CCFILE STA ICBALZ STY ICBAHZ JSR WDREAD ;READ THE SEGMENT END ADDRESS SEC ADC #0 BCC CCSUBT INY CCSU}BT SEC SBC ICBALZ ;CALCULATE THE LENGTH TO LOAD INTO RAM STA ICBLLZ TYA SBC ICBAHZ STA ICBLHZ BCS GETTXT ;BRANCH IF V}ALID LENGTH (GET DATA BYTES) LDY #181 ;ELSE, MEMORY WRAP ERROR BMI DKLERR ; WDXIT PLA PLA DKLERR TYA PHA JSR DKCLOS ;C}LOSE THE PROGRAM FILE PLA TAY ;AND RETURN ANY ERROR CODE RTS ; ; READ A WORD FROM THE PROGRAM FILE AND COMPARE IT WITH }$FFFF ; WDREAD LDA #0 STA ICBLLZ STA ICBLHZ ;SET LENGTH TO ZERO JSR DKREAD ;READ A BYTE BMI WDEOF PHA JSR DKREAD ;RE}AD THE SECOND BYTE BMI WDEOF1 TAY PLA CPY #$FF ;UPPER BYTE $FF? BNE TORTS ;NO, THEN WORD IS NOT $FFFF CMP #$FF ;YES,} IS LOWER BYTE $FF? TORTS RTS ;IF BOTH $FF, RETURN ZERO FLAG ; WDEOF1 PLA WDEOF CPY #136 ;IS THIS END OF FILE? BNE WDXIT } ;IF NOT, RETURN ERROR CODE PLA PLA ;ELSE, GET RID OF RETURN ADDR LDA ICPTLZ LSR A LSR A PHP JSR DKCLOS ;CLOSE FILE} AND SET Y=1 PLP BCS TORTS ;EXIT IF NO-RUN SPECIFIED JMP (RUNADR) ;THEN GO TO RUN ADDRESS ; ; INVOKE INIT FOR EVERY BLOC}K OF INPUT CODE (USUALLY JUST AN RTS) ; DOINIT JMP (INIADR) ;CALL INDIRECT ; ; XIO FUNCTION TO CREATE A NEW DIRECTORY ; ; P}ARSE DIRECTORY NAME ; MKDIR JSR GETFNM JSR SFDIR ;FIND FILE IN DIRECTORY BCS MKDMRD LDA #172 ;FILE ALREADY EXISTS DB $A}E ;SKIP 2 BYTES DISFUL LDA #169 ;DIRECTORY FULL JMP AEXIT ; ; READ IN BIT MAP ; MKDMRD LDA HOLFN BMI DISFUL JSR RBITMP } LDY MAPBUF DEY DEY STY DATBYT ; ; FIND EIGHT SECTORS FOR DIRECTORY ; LDA #LOW[369] ;FIRST AVAILABLE SECTOR AFTER ROOT D}IR. STA CURSEC,X LDA #HIGH[369] STA CURSEC+1,X LDA #0 STA TMP1 FDIRLP INC TMP1 JSR FNDLBIT ;IS THIS SECTOR FREE? BCS }FDIR2 AND MAPBUF,Y BCC FDIR1 FDIR2 AND MAPBUF+256,Y FDIR1 BNE FDIR3 STA TMP1 FDIR3 JSR INCCSEC LDA TMP1 CMP #8 BNE FDIR}LP ; ; ALLOCATE THE SECTORS USED ; ALCDLP JSR DECCSEC JSR FNDLBIT EOR #$FF BCS ALCPG2 AND MAPBUF,Y STA MAPBUF,Y BCC AL}CPG1 ALCPG2 AND MAPBUF+256,Y STA MAPBUF+256,Y LSR MAP2MOD ALCPG1 JSR DECCNT DEC TMP1 BNE ALCDLP ; ; WRITE ALLOCATION MAP} BACK TO DISK ; JSR FMTMAP ; ; ENTER NAME AND TYPE INFO INTO PARENT DIRECTORY ; LDA HOLFN JSR SDIRBK SEC JSR ENTNAME L}DA CURSEC+1,X STA DIRBUF+4,Y LDA CURSEC,X STA DIRBUF+3,Y LDA #0 STA DIRBUF+2,Y LDA #8 STA DIRBUF+1,Y ASL A JSR SAVFL}AG ; ; THEN CLEAR NEW DIRECTORY ; LDA #1 STA FMSBPT LDA CURSEC,X LDY CURSEC+1,X JMP CLRDIR DIRBUF+1,Y ASL A JSR SAVFLa; ; DOS DIRECTORY ROUTINES ; ; OPEN A DIRECTORY (FOR USER) ; LSTDIR LDY #$80-11 SAVFNB LDA FNAME-$80+11,Y STA (FMSBPT),Y IN}Y BPL SAVFNB JSR SFDIR ;FIND A MATCH IN THE DIRECTORY BCS ENDDIR ;IF NO MORE MATCHES, REPORT FREE SPACE NXTDIR JSR FMTDI}R ;ENTRY FOUND, FORMAT INTO A TEXT STRING LDA CURFNO STA FCBFNO,X ;SAVE THE FILE NUMBER OF THE ENTRY FOUND GODONE JMP DONE} ;AND RETURN ; GOTEOD DEC DATBYT ;CONVERT EOL TO $9B (REAL EOL) STA CURLEN,X ;AND FINISH UP BNE GODONE ; DIRRD LDY #$80-1}1 RSTFNB LDA (FMSBPT),Y ;FETCH BYTES OF PREVIOUSLY PARSED DIRECTORY ENT STA FNAME-$80+11,Y INY BPL RSTFNB LDA CURLEN,X B}MI DIREOF ;EOF IF WE ALREADY REPORTED FREE SPACE TAY LDA (FMSBPT),Y STA DATBYT INC CURLEN,X CMP #$9C BEQ GOTEOD CMP #}$9B ;IS THIS END OF LINE? BNE GODONE ;IF NOT, CONTINUE FETCHING OLD BYTES LDA FCBFNO,X CMP CURFNO BNE DMSTRD CPX DIUNI}T BEQ DRDNRQ DMSTRD JSR RRDIR ;IF SO, INSURE DIRECTORY BLOCK IS IN MEMORY DRDNRQ JSR CSFDIR ;AND FIND THE NEXT ENTRY BCC }NXTDIR ;IF FOUND, LOOP BACK AND FORMAT IT ; ; NO MORE ENTRIES, REPORT FREE SECTORS LAST ; ENDDIR JSR RBITMP ;READ THE VTOC} DATA LDY #0 STY CURMAP ;FORCE A REREAD NEXT TIME LDA MAPBUF+3 LDX MAPBUF+4 ;AND STUFF THE BUFFER WITH NO. OF FREE SECTO}RS JSR CVTDEC LDX #-14 FSECL LDA FSECM+14-256,X ;FOLLOWED BY THE "FREE SECTORS" TEXT STA (FMSBPT),Y INY INX BNE FSECL }BEQ GODONE ; DIREOF JMP RETEOF ;NO MORE LINES, RETURN EOF INDICATION ; FSECM DB ' FREE SECTORS',$9C ; ; FORMAT A DIRECTORY }ENTRY FOR BASIC, ETC. ; FMTDIR LDY #' ' LDX DIRDSP LDA DIRBUF,X PHA AND #$20 BEQ D0E35 LDY #'*' ;IF SO, MARK AS LOCKED }D0E35 TYA LDY #0 STA (FMSBPT),Y PLA LDY #' ' AND #$10 BEQ NOTDIR LDY #':' NOTDIR TYA LDY #1 STA (FMSBPT),Y CPYNAML I}NY LDA DIRBUF+5,X STA (FMSBPT),Y INX CPY #13 BCC CPYNAML ; LDA #' ' STA (FMSBPT),Y LDY DIRDSP LDA DIRBUF+1,Y LDX DI}RBUF+2,Y LDY #14 ;SECTOR COUNT STARTS HERE ; ; CONVERT A 16-BIT INTEGER TO A 4 OR 5 DIGIT NUMBER ; CVTDEC STX TMP2 STA TMP}1 LDX #HIGH[10000] LDA #LOW[10000] JSR MKDGT2 CMP #'0' BNE SKIP5 DEY SKIP5 LDX #HIGH[1000] LDA #LOW[1000] JSR MKDGT2 } LDA #100 ;FOR THE SHORT STUFF JSR MAKDGT LDA #10 JSR MAKDGT TXA ADC #'0'+10 STA (FMSBPT),Y INY LDA #$9B ;TERMINATE} LINE STA DATBYT STA (FMSBPT),Y LDA #0 LDX CURFCB STA CURLEN,X RTS ; ; CREATE A DIGIT AND STORE IT INTO THE DIRECTORY }BUFFER ; MAKDGT LDX #0 ;IF SUBTRAHEND < 256, ZERO UPPER BYTE MKDGT2 STX DIRDSP STA DIRSEC STY DATBYT LDY #'0' SEC DGTLP2} LDA TMP1 SBC DIRSEC TAX LDA TMP2 SBC DIRDSP BCC DGTXIT STA TMP2 STX TMP1 INY BCS DGTLP2 ; DGTXIT TYA LDY DATBYT S}TA (FMSBPT),Y INY RTS ; ; PARSE A FILE NAME WITH WILD CARD CHARACTERS ('*' AND '?') ; GETNM2 iny ;look for ">" in lda (}ICBALZ),y ;the start of cmp #'>' ;the filename beq GETNAM ;(for SpartaDOS compatibility) dey ;[Bob Puff] bne GETNAM };branch always ; GETFNM LDX CURFCB LDY #HIGH[361] LDA #LOW[361] JSR SETDIR INY LDA (ICBALZ),Y INY CMP #':' ;DEFAULT D}IRECTORY? BNE GETNM2 ;IF NOT, CHECK FOR SPARTA ">" DEY STY TMP1 LDY DEFAULT STY ICDNOZ TYA STA ICDNO,X JSR SETUPD L}DA CDIREC LDY CDIREC+1 JSR SETDIR LDY TMP1 ; GETNAM LDX #-11 INY AFTSTR LDA (ICBALZ),Y CMP #'*' BNE TSTPER LDA #'?' I}NY QLOOP STA FNAME+11-256,X INX BPL TOXITC ;END OF EXTENSION? PERFND CPX #-3 ;END OF FILE NAME? BNE QLOOP ;NO MORE -?-S} BEQ AFTSTR ; TSTPER CMP #'.' ;A PERIOD? BNE TSTCHR ;IF NOT, CHECK FOR INDIVIDUAL CHARACTERS LDA #' ' ;IF SO, FILL WITH} SPACES INY BNE PERFND ; TSTCHR CMP #'?' BCC ENDCHR ;IF < '?', CHECK FOR DIGIT CMP #'Z'+1 ;ELSE, UPPER CASE LETTER, '?'}, OR '@'? BCC GOTCHR CMP #'_' BCC ENDCHR ;IF CARET, BACKSL. OR BRACKETS CMP #'z'+1 ;LOWER CASE, ACCENT OR UNDERSCORE? }BCC GOTCHR ENDCHR CPX #-11 ;IF FIRST CHAR, ERROR BEQ ERRCHR ;NO BYTES IN FILE NAME CMP #'0' ;ELSE, A DIGIT? BCC FILLNM } ;IF NOT, THIS IS END OF NAME CMP #':' BCS FILLNM ; GOTCHR STA FNAME+11-256,X INY INX BMI AFTSTR ; TOXITC LDA (ICBALZ),Y} TSTDIR CMP #':' ;LOOK FOR SUBDIRECTORY BEQ MYDIR ;IF MYDOS SYNTAX CMP #'>' ;OR SPARTA SYNTAX BNE XITCHR ;IF FINISHED,} RESTORE FCB PTR TO X AND EXIT MYDIR STY TMP2 JSR SFDIR ;ELSE, FIND FILE BCS FNER1 ;NO SUCH FILE JSR TONXDR BEQ FNER1 }LDY TMP2 BNE GETNAM FNER1 LDA #174 ;IF NOT, RETURN ERROR 174 DB $2C ;BIT ABS (SKIP 2 BYTES) ; ERRCHR LDA #165 JMP AEXIT ; }FILLNM PHA LDA #' ' FILLLP STA FNAME+11-256,X INX BMI FILLLP PLA JMP TSTDIR ; ; RETURN WITH NON-ZERO FLAG IF FILE IS A }DIRECTORY ; TONXDR LDA #$10 ;FILE FOUND, A DIRECTORY? JSR GETFLAG BEQ TONXIT ;IF NOT, SET ZERO FLAG LDA DIRBUF+3,Y ;IF S}O, MOVE POINTERS TO THE NEW LEVEL STA DIRBAS,X LDA DIRBUF+4,Y STA DIRBAS+1,X LDA #$10 ;AND CLEAR THE ZERO FLAG TONXIT RT}S ; ; ENTER A NAME INTO THE DIRECTORY AT DIRBUF[DIRDSP] ; ENTNAME PHP LDX #-11 LDY DIRDSP NAMELP LDA FNAME+11-256,X ;LOAD }THE MASK CHARACTER CMP #'?' BNE STORIT ;IF NOT '?', SAVE IT AS IT APPEARS PLP PHP BCC NOSTOR ;IF CY CLEAR, LEAVE THE C}HARACTERS UNCHANGED LDA #' ' ;IF CY SET, CONVERT '?'S TO SPACES STORIT STA DIRBUF+5,Y NOSTOR INY INX BMI NAMELP PLP LDY} DIRDSP XITCHR LDX CURFCB RTS ; SFDIR JSR WBITMP ;INSURE BIT MAP IS SAFE LDX #255 STX HOLFN STX CURFNO INX STX DAUX2 }INX STX DAUX1 LDX #READ STX DCOMND JSR SYSSET ;SET UP POINTERS FOR SYSTEM BUFFER I/O ; LDA ICDNOZ CMP RAMDKU BEQ CSFD}IR ;IF RAMDISK, FORGET DENSITY CHECK ldx CURFCB ;IF A ROOT DIRECTORY ACCESS, READ BOOT SECTOR lda DIRBAS,X ;IF IN A SUBDI}RECTORY, ASSUME DENSITY IS OK cmp #LOW[361] ;[Bob Puff] bne CSFDIR ;;; lda DIRBAS+1,X ;Only occasionally will we get an ext}ra read! ;;; cmp #HIGH[361] ;;; bne CSFDIR ; JSR DSKINV ;ELSE, READ THE FIRST BOOT SECTOR BMI ERRX JSR INVUNIT ;UPDATE D}RIVE CONFIGURATION ; CSFDIR INC CURFNO ;READ NEXT 16-BYTE DIR. BLOCK LDA CURFNO JSR BSECDS ;CONVERT TO SECTOR AND DISPLAC}EMENT XITCH1 BCS XITCHR BNE NOREAD ;IF DISP>0, PROCESS BLOCK JSR RDIRBK ;IF DISP=0, READ SECTOR ; NOREAD LDY DIRDSP LDA }DIRBUF,Y BEQ FNDOLD ;ZERO IS END OF DIRECTORY (NO MORE ENTRIES) BMI FNDOLD ;NEGATIVE IS EMPTY SLOT (MAY HAVE MORE ENTRIES}) ; ; HANDLE DOS 2.5 FILES ; and #$DF ;preserve lock flag cmp #3 ;is this DOS 2.5 + file? bne NOD25 ;nope lda #$41 ;}otherwise, kludge the eor DIRBUF,Y ;flag to make $42 sta DIRBUF,Y ;and save lock. ; NOD25 AND #$01 ;IGNORE ANY FILE THAT I}S MARKED "OPEN" BNE CSFDIR LDX #-11 CPNXCH LDA FNAME+11-256,X CMP #'?' BEQ WCMTCH ;EVERYTHING MATCHES "?" CMP DIRBUF+5,}Y BNE CSFDIR ;NO MATCH, LOOK AT THE NEXT DIRECTORY ENT WCMTCH INY INX BMI CPNXCH CLC BCC XITCHR ;ENTRY FOUND, RETURN W}ITH CY=0 ; FNDOLD LDX HOLFN BPL KPOLD ;IF AN EMPTY SLOT IS ALREADY FOUND, DO NOTHING LDX CURFNO STX HOLFN ;ELSE SAVE THI}S ONE, ITS THE FIRST! KPOLD TAX BMI CSFDIR ;IF NOT END OF THE DIRECTORY, KEEP LOOKING ERRX SEC BCS XITCH1 ;ELSE, ENTRY NO}T FOUND, RETURN WITH CY=1 ; ; DOS I/O ROUTINES ; ; DISK SECTOR I/O ROUTINES ; WRDISK SEC ;FMS DISK WRITE ENTRY RWDISK LDY }FMSBPT ;DATA SECTOR READ/WRITE ENTRY LDA FMSBPT+1 JSR BUFSET LDA CURSEC+1,X LDY CURSEC,X FMDKIO PHP LDX DUNIT CPX RAMD}KU BEQ RDKIO1 PLP pha ;ALLOW FOR DENSITY CHANGE IN FORMAT, ETC. lda SECSIZ-1,X ;[Bob Puff] tax pla JMP DKIO ; RDKIO1} JMP RDKIO ;ABSOLUTE DISK I/O ROUTINE WAS MOVED TO LOW RAM ; EXTEND JSR ALLOC LDA FCBOTC,X LSR A BCC REWRIT DEC FCBOTC,X} JSR WTRICK JMP WRTTST ; REWRIT LDY LNKSEC+1,X LDA LNKSEC,X JSR SAVLNK WRTTST BMI RTBADF INC SECCNT,X BNE TONXT INC SE}CCNT+1,X ; TONXT LDA LNKSEC,X ;MAKE NEXT SECTOR STA CURSEC,X ;NEW CURRENT SEC. LDA LNKSEC+1,X STA CURSEC+1,X LDA #0 STA }LNKSEC,X ;ZERO LINK STA LNKSEC+1,X LENSET STA CURLEN,X ;ZERO CURRENT OFFSET LDA DLINK ;GET THE LINK LOC. STA MAXLEN,X ;MA}KE IT MAX. LEN. CLC ;CLEAR CY FOR LATER READ RTS ; RDNXTS LDA FCBFLG,X BEQ CHASE ; WRNXTS LDA FCBFLG,X BMI EXTEND ASL }A BPL RDNXTS ASL A STA FCBFLG,X JSR WRDISK BPL RDNXTS ; RTBADF JMP HWERR ;RETURN HARDWARE ERROR CODE IF PRESENT ; SAVLN}K PHA TYA LDY DLINK STA (FMSBPT),Y PLA INY STA (FMSBPT),Y INY LDA CURLEN,X NOBIT STA (FMSBPT),Y LDY FCBOTC,X BMI LE}N16 ;16-BIT LENGTH? LDA FCBFNO,X ASL A ASL A LDY DLINK ORA (FMSBPT),Y STA (FMSBPT),Y LEN16 JMP WRDISK ; WTRICK LDA LNK}SEC,X STA SAVSEC,X LDA LNKSEC+1,X STA SAVSEC+1,X STX LSTIOCB LDA CURSEC,X STA LSTSEC LDA CURSEC+1,X STA LSTSEC+1 JMP} WRDISK ; INSTRT JSR INITYP ; CHASE LDA LNKSEC,X ORA LNKSEC+1,X BEQ NOLINK JSR TONXT ;SET CY=0, FUNC=READ JSR RWDISK BM}I RTBADF ;CANNOT READ SO BAD FILE NUMBER(ERR=164) LDY DLINK LDA FCBOTC,X ;16-BIT LINK? ORA #$7F BMI LNGLNK LDA (FMSBPT)},Y LSR A LSR A CMP FCBFNO,X BNE XLINKED LDA #$03 LNGLNK AND (FMSBPT),Y STA LNKSEC+1,X INY LDA (FMSBPT),Y STA LNKSEC,}X INY LDA (FMSBPT),Y STA MAXLEN,X DRDXIT CLC RTS ; XLINKED LDA ICCOM,X CMP #FMTCMD ;IS THIS A FORMAT? BNE FNOERR NOLIN}K SEC RTS ; ; READ OR WRITE A DIRECTORY BLOCK ; RRDIR LDA FCBFNO,X ; SDIRBK STA CURFNO RDCFNO LDA CURFNO JSR BSECDS ; RDIRB}K JSR WBITMP ;TAKE CONTROL OF SYSTEM BUFFER CLC DB $A9 ;LDA # (SKIPS 1 BYTE) WDIRBK SEC RWDBK PHP LDX CURFCB ;PUT FCB N}O. IN X STX DIUNIT ;SAVE THE DIR. BUFFER IOCB JSR SYSSET CLC LDA DIRSEC ADC DIRBAS,X TAY LDA DIRBAS+1,X ADC #0 ;MUL}TIPLE DIRS. REQ. THIS [ChasM] PLP SYSRW JSR FMDKIO BPL DRDXIT LDA #163 ;BIT MAP R/W ERROR, RETURN SYSTEM ERR. CODE DB $A}E ;SKIP 2 BYTES ; FNOERR lda #164 sta DSTATS jmp HWERR ;FILE NUMBER MISMATCH ; ; READ OR WRITE THE DISK VTOC (BIT MAP) ; }RBITMP LDA CURMAP CMP ICDNOZ BEQ MAPXIT ;SKIP READ IF WHAT WE WANT IS ALREADY THERE JSR WBITMP ;ELSE, REAL I/O, SAVE CUR}RENT BUFFER CONTENTS ; LDA #0 TAY ZMAP STA MAPBUF,Y ;ZERO ENTIRE 512 STA MAPBUF+256,Y ;BYTES OF MAP BUF. DEY BNE ZMAP C}LC JSR RWBMAP ;THEN READ 128 OR 256 BYTES OF VTOC DATA ; LDY #$FF STY DIUNIT ;INDICATE MAP (NOT DIR) IS LOADED STY MAP2} ;INDICATE SECOND PAGE OF MAP IS UNLOADED INY STY CHGMAP ;INDICATE MAP IS UNCHANGED INY STY MAP2MOD STY CURMP ; MAPCLR} STA CURMAP ;AND SAVE DRIVE NUMBER MAP APPLIES TO MAPXIT RTS ; WBITMP LDA CHGMAP BEQ MAPCLR ;IF MAP NOT CHANGED, SKIP WRIT}ING IT STA DUNIT FMTMAP LDA #0 STA CHGMAP ;ELSE MARK IT UNUSED STA CURMAP lda DUNIT ;save drive # [Bob Puff] pha SEC } JSR RWBMAP pla ;then restore it [Bob Puff] sta DUNIT ; WRNXTM LDA MAP2MOD BNE NOMPI2 ;IF THE PAGE BUFFER IS CLEAN, JU}ST EXIT LDA #$FF ;ELSE, WRITE IT TO DISK PHA LDA MAP2 INC MAP2MOD SEC BCS MUSTWM ; RDNXTM CMP MAP2 ;READ A PAGE INTO }THE SECOND PAGE BUFFER BEQ NOMAPI ;IF IT IS ALREADY THERE, JUST EXIT PHA JSR WRNXTM ;ELSE, WRITE THE CURRENT PAGE (IF NE}CESSARY) PLA ;AND READ THE NEW ONE PHA CLC ;BY FALLING INTO MUSTWM WITH CY=0 ; MUSTWM PHA LDA #HIGH[MAPBUF+256] LDY }#LOW[MAPBUF+256] JSR BUFSET ;SET UP THE BUFFER POINTER FOR 2ND PAGE PLA ; OF THE VTOC BUFFER JSR MAPIOC ;ISSUE I/O RE}QUESTS PLA STA MAP2 ;UPDATE SECOND BUFFER ID BYTE NOMAPI RTS ; RWBMAP JSR SYSSET ;SET UP BUFFER POINTERS FOR SYSTEM BUF I}/O LDA #0 MAPIOC PHP pha ldx DUNIT ;NOTE: THE CURRENT I/O MAY NOT BE TO THE lda SECSIZ-1,X ;FCB BEING ACCESSED! tax };[Bob Puff] pla cpx #2 ;256 BYTE SECS? beq MAPDDS ASL A ;128, CHANGE PAGE NUMBER TO PAIR NUMBER MAPDDS EOR #$FF SEC A}DC #LOW[360] TAY cpx #2 ;128 OR 256 BYTE SECTORS? beq DDMAPX ;IF 128, READ 2 SECTORS TO FILL BUFFER LDA #HIGH[360] PLP} PHP JSR SYSRW ;READ OR WRITE THE FIRST SECTOR LDA MAPBUF CMP #3 ;IF DOS 2.0 DISK, READ ONE SECTOR BCC XITMBF ;EVEN I}N SINGLE DENSITY JSR STEPBP DEY DDMAPX LDA #HIGH[360] PLP PHP JSR SYSRW ;READ OR WRITE THE SECOND (OR ONLY) SECTOR XITM}BF PLP NOMPI2 LDA ICDNOZ STA DUNIT ;RESTORE THE USER DRIVE NUMBER TO DUNIT, RTS ;SINCE I/O MAY HAVE BEEN TO ANOTHER DRIV }E ; SYSSET LDA #HIGH[MAPBUF] LDY #LOW[MAPBUF] JMP BUFSET ; ; ROUTINE TO STEP TO THE NEXT DIRECTORY ENTRY (UNTIL WE RUN OUT }) ; BSECDS LDY #0 STY DIRDSP LSR A ROR DIRDSP LSR A ROR DIRDSP LSR A ROR DIRDSP ;(FILE NUMBER MOD 8) * 16 IS OFFSET I }N SECTOR STA DIRSEC ;FILE NUMBER/8 IS SECTOR OFFSET ; CMP #8 ;END OF DIRECTORY? DEY BCS BSECXT ROR DIRDSP BSECXT RTS I|; ; DOS ALLOCATION ROUTINES ; ; FREE A SECTOR FOR LATER USE ; FREE JSR RBITMP ;MAKE SURE WE HAVE THE RIGHT MAP STA CHGMAP F" }MTFRE INC MAPBUF+3 ;BUMP LOW BYTE OF FREE SECTOR COUNT BNE FREE0 ;IF NO CARRY INC MAPBUF+4 FREE0 JSR FNDBIT PHA LDA TMP2"} BEQ SBMP1 STY TMP2 CMP CURMP ;BEFORE FIRST HOLE? BCS SBMP2 ;NO, LEAVE UNCHANGED STA CURMP ;YES, NEW FIRST HOLE SBMP2"} JSR RDNXTM LDY TMP2 LSR MAP2MOD ;MARK MAP PAGE2 DIRTY PLA ORA MAPBUF+256,Y STA MAPBUF+256,Y RTS ; SBMP1 PLA ORA MAPB"}UF,Y STA MAPBUF,Y RTS ; ; FIND BIT ASSOCIATED WITH A SECTOR ON THE DISK ; FNDBIT LDA CURSEC,X AND #7 ;EXTRACT THE BIT NUMB"}ER TAY SEC LDA #0 FREE1 ROR A ;POSITION CARRY TO THE BIT TO FLIP DEY BPL FREE1 PHA ;SAVE THE BIT MASK ; LDA CURSEC,X "} CLC ADC #10*8 ;ALLOW FOR 10 BYTE HEADER TAY ;SAVE LOW BYTE LDA CURSEC+1,X ADC #0 ;PROPOGATE CARRY LSR A STA TMP2 TYA"} ROR A LSR TMP2 ROR A LSR TMP2 ROR A TAY ; PLA ;RESTORE THE BIT MASK RTS ; ; ALLOCATE AN UNUSED SECTOR TO A FILE ; A"}LLOC JSR RBITMP STA CHGMAP LDY #10 LDA #0 STA TMP2 ALL1 CMP MAPBUF,Y ;ANY BITS LEFT? BNE SECFN1 ;IF SO INY BNE ALL1 ;"} SEC LDA MAPBUF SBC CURMP SEC SBC #3 STA TMP1 ALLCK BMI ALGONE LDA CURMP STA TMP2 JSR RDNXTM LDA #0 TAY ALL2 CMP M"}APBUF+256,Y BNE SECFN2 ;IF FREE SECTOR IN SECOND PART OF MAP INY BNE ALL2 INC CURMP ;TO NEXT SECTOR OF BIT MAP DEC TMP"}1 BPL ALLCK ; ALGONE DEC CURMP DFERR LDA #162 ;DISK FULL ERROR CODE JMP AEXIT ;IF THIS IS IT, ERROR-EXIT ; SECFN1 SEC LD"}X #$AF ;I.E., -8*10 - 1 ALL3 ROR A INX CMP MAPBUF,Y BCC ALL4 CLC BNE ALL3 ALL4 EOR MAPBUF,Y STA MAPBUF,Y BPL ALL7 ; S"}ECFN2 SEC LDX #$AF ;I.E., -8*10 - 1 ALL5 ROR A INX CMP MAPBUF+256,Y BCC ALL6 CLC BNE ALL5 ALL6 LSR MAP2MOD EOR MAPBUF"}+256,Y STA MAPBUF+256,Y ; ALL7 TYA ASL A ROL TMP2 ASL A ROL TMP2 ASL A ROL TMP2 STA TMP1 TXA ADC TMP1 LDX CURFCB "}STA LNKSEC,X LDA TMP2 ADC #$FF STA LNKSEC+1,X DECCNT LDA MAPBUF+3 BNE NOBOR DEC MAPBUF+4 NOBOR DEC MAPBUF+3 CLC RTS ; "}; SIMULATE OLD STYLE BIT FINDER ; FNDLBIT JSR FNDBIT PHA ;SAVE MASK LDA TMP2 ;FIRST PAGE? BEQ FNDPG0 STY TMP2 ;SAVE "}OFFSET IN PAGE CMP DATBYT BCS DFEJMP JSR RDNXTM ;READ IN PROPER PAGE LDY TMP2 ;THEN RESTORE A AND Y REGS PLA SEC ;S"}ET CY (PAGE 1 BUFFER USED) RTS ; FNDPG0 PLA ;RESTORE SAVED MASK CLC ;AND CLR CY (SAY PAGE 0) RTS ; DFEJMP JMP DFERR ; "}DECCSEC LDA CURSEC,X BNE ALCPG0 DEC CURSEC+1,X ALCPG0 DEC CURSEC,X RTS ; INCCSEC INC CURSEC,X BNE DELDIN INC CURSEC+1,X " }DELDIN RTS ; ; DOS MISC. SUBROUTINES ; ; SET UP STATE VARIABLES ON ENTRY ; SETUP LDY ICDNOZ ;GET UNIT NO. SETUPW STX CURFCB "!} TSX INX INX STX STKPSV ;SAVE POINTER TO RETURN ADDR ON STACK SETUPD STY DUNIT ;COPY UNIT NO. TO DCB LDA #1 CPY RAMDKU ""}BEQ UFIXED ;RAMDISK SECTOR SIZE IS ALWAYS 128 BYTES LDA SECSIZ-1,Y BEQ INVUNIT ;IF NOT CURRENTLY VALID UNIT, TEST FOR DENSI"#}TY UFIXED STA SECDAT ;OTHERWISE, STORE CORRECT DENSITY DATA LSR A ROR A ROR A ORA #$7D ;UPDATE THE LINK POSITION IN THE D"$}ISK SECTOR STA DLINK ; LDX CURFCB LDY BUFNO,X ;GET THE BUFFER NUMBER BNE RSETUP LDY FILES ;IF ONE IS NOT ALLOCATED IN"%}Y SFORB DEY BEQ NOSECB ;ALLOCATE ONE, OR ABORT THE OPERATION NOW LDA BUFFLG-1,Y BNE SFORB LDA #$80 STA BUFFLG-1,Y TYA "&} STA BUFNO,X RSETUP LDA DOSEND ;==SBTABL STA FMSBPT LDA SBTABU-1,Y STA FMSBPT+1 RTS ; INVUNIT JSR JSTRD BNE UFIXED ; NOU"'}NIT LDA #160 ;RETURN ST=160, DRIVE NOT PRESENT DB $AE ;SKIP TO JMP INSTRUCTION NOSECB LDA #161 ;RETURN ST=161, NO MORE FILE "(}BUFFERS JMP AEXIT ; ; REMOVE DOS POINTER FROM BOOT SECTORS ; TDDOS JSR TSTDOS ;MUST WE UPDATE BOOT? BNE NODOSX ;NO, RETURN")} ; DELDOS LDY #0 ;YES, REMOVE DOS POINTER FROM BOOT BEQ UPDBT ; ; ADD DOS POINTER TO BOOT SECTORS ; SETDOS STY DOSLOC STA "*}DOSLOC+1 LDY SECDAT UPDBT LDA DUNIT CMP RAMDKU BEQ TDEXIT STY SECDAT LDA STATE PHA LDA DEFAULT PHA LDA #$00 STA STA"+}TE ;NOTHING IS IN MEMORY YET LDY #$FF LDA FCBOTC,X BMI NOAND ;LONG LENGTH FIELD? LDY #$03 ;IF NOT, USE ONLY 10 BITS NO",}AND STY ANDCD+1 LDA #HIGH[BOOTFL] LDY #LOW[BOOTFL] JSR BUFSET LDY #0 STY DAUX2 ; WSECL INY STY DAUX1 LDX #1 STX DEFAU"-}LT SEC JSR DKIO2 JSR STEPBP CPY BOOTL BNE WSECL ; PLA STA DEFAULT PLA STA STATE LDY ICDNOZ STY DUNIT LDA SECSIZ-1".},Y STA SECDAT NODOSX RTS ; ; TEST FOR FILE NAME = 'DOS.SYS' ; TSTDOS LDY #256-11 LDX DIRDSP TDLOOP LDA DIRBUF+5,X EOR DOS"/}SYS-256+11,Y BNE TDEXIT INX INY BNE TDLOOP TDEXIT LDX CURFCB TAY RTS ; DOSSYS DB 'DOS SYS' ; ; FIND AT LEAST ONE F"0}ILE MATCHING GIVEN NAME ; LFFILE JSR GETFNM ;EXTRACT FILE NAME FROM BUFFER STY TMP2 ;SAVE IT FOR -RENAME- JSR SFDIR ;FIND F"1}IRST MATCHING FILE IN DIR LDA #170 ;IF NONE, RETURN ERROR 170 BCS AEXIT ;ELSE, RETURN RTS ; ; RETURN ERROR IF FILE IS LOC"2}KED ; TSTLOK LDA #$20 ;CHECK BIT 5 JSR GETFLAG BEQ TDEXIT LDA #167 ;FILE LOCKED ERROR = 167 DB $AE ;SKIP 2 BYTES ; ; RET"3}URN WITH NO ERROR ; DONE LDA #1 ;NORMAL COMPLETION ; ; RETURN ERROR CODE IN ACC TO CIO (IN Y) ; AEXIT LDX STKPSV ;RESTORE ST"4}ACK POINTER TXS LDX CURFCB ;RESTORE IOCB OFFSET TO X-REG STA ICSTA,X ;RETURN STATUS IN IOCB TAY ;RETURN STATUS IN Y-REG "5} LDA DATBYT CPY #0 RTS ; ; RETURN HARDWARE ERRORS TO CIO ; HWERR ;;; lda #0 ;fix VTOC updating bug ;;; sta CURMAP ;do we"6} really want to do this????? ;;; sta CHGMAP ;[Bob Puff] LDA DSTATS BNE AEXIT ; ; RELEASE FCB AND RETURN NO-ERROR STATUS "7}; FREDON LDX CURFCB ; LDY BUFNO,X ;FINISHED WITH THE SECTOR BUFFER, RETURN IT BEQ DONE ;IF NONE ALLOCATED, SO WHAT! LDA #0"8} STA BUFNO,X STA BUFFLG-1,Y BEQ DONE ; ; TEST OR CLEAR A BIT IN THE FLAG BYTE ; GETFLAG LDY DIRDSP AND DIRBUF,Y RTS ; ;"9} SAVE FLAG BYTE AND WRITE BACK TO DIRECTORY ; SAVFLAG LDY DIRDSP STA DIRBUF,Y JMP WDIRBK LDY DIRDSP AND DIRBUF,Y RTS ; ; \ TITLE 'MYDOS UTILITIES PROGRAM' LIST I ; Copyright 1984, Charles Marslett, Wordmark Systems ; ; Permission is granted by &;}the author for any use whatsoever of this ; code, so long as this notice remains in the source code, and so ; long as t&<}he source to this routine, however modified or unmodified, ; is made available for a nominal cost. ; ; FMS ENTRY POINTS (&=}These should not be changed lightly!) ; ; [Data] ; FILES = $0709 ;MAX NUMBER OF OPEN DISK FILES RAMDKU = $070A ;LOC OF RAM&>} DISK DRIVE NO DFUNIT = $070B ;CURRENT DEFAULT UNIT NUMBER SECDAT = $070E ;CURRENT I/O SECTOR SIZE (1=128, 2=256) DLINK = $&?}0711 ;OFFSET TO THE LINK FIELD IN EACH SECTOR ANDCD = $0734 ;OFFSET TO THE MASK EXTRACTING NEXT SECTOR BITS DKIO2 = $0769 &@};SECTOR I/O SUBROUTINE ENTRY POINT WRCMD = $0779 ;ADDRESS OF WRITE COMMAND BYTE (50/57) STATE = $07BE ;CURRENT STATE OF DUP&A}/MEM/AUTORUN DKTYPE = $07C4 ;DISK SECTOR SIZE TABLE (8 BYTES) DRVDEF = $07CC ;FLOPPY DRIVE CONFIGURATION TABLE (8-BYTES) MD&B}INIT = $07E0 ;MDOS initialization code MAPBUF = $0908 ;512-BYTE BUFFER DOWN IN RESIDENT AREA HDTAB = $0B15 ;HARD DISK DRIV&C}E SIZE TABLE (0 = FLOPPY) WOTDCB = $0B25 ;PROTOTYPE DRIVE MODE SET TABLE MAPAGE = $0BBA ;Page configuration table (64-bytes&D}) in MDOS ; ; [Code] ; CONFIGR = $0B2F ;CONFIGURE DRIVE SUBROUTINE ENTRY RDCONF = $0B9A ;READ CONFIGURATION STATE SUBROUTI&E}NE ENTRY STEPBP = $0C5D ;STEP TO THE NEXT BOOT SECTOR BUFFER ADDRESS ; ; ; RAM disk I/O driver patch locations ; RDKLMT = $&F}0C3A ;Size of RAM disk RDAD1 = $0C0D ;Three locations where the control address RDAD2 = $0C19 ; needs to be stored RDAD3 &G}= $0C4C NMLMAP = $0C14 ;Mask (1=part of mapping register) ; ; Starting location for the MDUP code ; ORIGIN = $1AE0 ;FIRST &H}BYTE AFTER MDOS(19CE - 4.00) ; ; Patches linking MDUP into MDOS ; ORG $70C DW RESEND ;START OF FREE MEMORY (end of reside&I}nt stuff) ; ORG $085E JMP INIT ;DUP INITIALIZATION ENTRY POINT ; ; ; DEFINED VALUES ; CR = $9B EOF = $88 ; OPEN = 3 GETRE&J}C = 5 GETCHR = 7 PUTCHR = 11 CLOSE = 12 RENAME = 32 DELETE = 33 LOCK = 35 UNLOCK = 36 FORMAT = 254 ; ; ROM AND RAM ADDRESSES&K} ; CARTST = $BFFA ; AUDF1 = $D200 AUDCTL = $D208 SKRES = $D20A SERIN = $D20D SEROUT = $D20D IRQEN = $D20E SKCTL = $D20F PBCTL&L} = $D303 ; FASCII = $D8E6 IFP = $D9AA EDITRV = $E400 DSKIO = $E453 CIOV = $E456 SIOV = $E459 SETVBV = $E45C CIOINV = $E46E ; &M}WARMST = $08 DOSVEC = $0A DOSINI = $0C POKMSK = $10 BRKKEY = $11 RAMLO = $1A ; DUNITZ = $21 DCMDZ = $22 DBUFZ = $24 DLENZ = $&N}28 DAUX1Z = $2A DAUX2Z = $2B DAUX3Z = $2C ; LMARGN = $52 RMARGN = $53 ; FR0 = $D4 VECTOR = $D4 HDBUF = $D6 BUFAD = $DA BUFLEN&O} = $DC FNPTR = $DE TEMP = $E0 TEMP2 = $E1 ; INBUFF = $F3 ; VSERIN = $20A VIMIRQ = $216 CDTMV3 = $21C CDTMF3 = $22A SHFLOK = $&P}2BE RUNAD = $2E0 INITAD = $2E2 MEMTOP = $2E5 MEMLO = $2E7 DVSTAT = $2EA ;SYSTEM STATUS BUFFER ; DDEVIC = $300 DUNIT = $301 D&Q}CMD = $302 DSTAT = $303 DBUF = $304 DTIMEO = $306 DLEN = $308 DAUX = $30A HATABS = $31A ; IOCB = $340 ICDNO = $341 ICMD = $34&R}2 ISTAT = $343 IBUF = $344 ILEN = $348 IAUX = $34A ; ORG ORIGIN ;START OF MDUP ; INCLUDE D:MDUP1.ASM ;RESIDENT CODE ; MSBA&S}SE = * ;START OF NON-RESIDENT CODE ; INCLUDE D:MDUP2.ASM ;DATA AREAS AND THE MAIN MENU ; INCLUDE D:MDUP3.ASM ;COPY, LIST, &T}CREATE, AND DELETE FUNCTIONS ; INCLUDE D:MDUP4.ASM ;ENTIRE DISK FUNCS (FORMAT, COPY, WRT BOOT) ; INCLUDE D:MDUP5.ASM ;PROGR&U}AM LOAD AND SAVE FUNCTIONS ; INCLUDE D:MDUP6.ASM ;CONFIGURATION FUNCTIONS ; INCLUDE D:MDUP7.ASM ;MISC. SUBROUTINES ; DUPEND&V} = * DUPLEN = DUPEND-DUPBASE MSLEN = DUPEND-MSBASE END MENUSL N FUNCTIONS ; INCLUDE D:MDUP7.ASM ;MISC. SUBROUTINES ; DUPEND$?; ; Resident MDUP code ; ; INITIALIZE MYDOS INTERFACE ; INIT LDA #HIGH[DUPENT] STA DOSVEC+1 LDA #LOW[DUPENT] STA DOSVEC *X}; LDA #0 STA FNAME LDA #$20 BIT STATE BNE CKMDOS ;IF WARM START CHECK FOR DUP LOADED ; ; COLD START CODE ; STA STATE *Y} ;SET MODE TO WARMSTART LDX #$10 JSR SOPEN ;RUN AUTORUN.SYS FILE DB 6 DB 39 DW AFN BMI CLOSX JSR CLOSX JMP (RUNAD) ;*Z} ; CLOSE IOCBS 10 AND 20 ; CLOSX JSR CLOS20 CLOS10 LDX #$10 ;CLOSE IOCB 10 DB $2C ;SKIP 2 BYTES CLOS20 LDX #$20 ;CLOSE I*[}OCB 20 CLOS2 LDA #CLOSE ;CLOSE ANY IOCB SCMD STA ICMD,X JMP CIOV ; DBUF10 LDX #$10 DEFBUF STA IBUF,X TYA STA IBUF+1,X CKM*\}DOS RTS ; ; Moved AUTORUN.SYS filename here so SUPERARC will not think ; this is >=4.3 DOS ; AFN DB 'D1:AUTORUN.SYS',$9B ; *]}; OPEN FILE ; ; CALLING SEQUENCE: ; JSR SOPEN ; DB AUX ; DB CMD ; DW BUFFER ADDRESS ; SOPEN SEC DB $A9 ;LDA *^}#IMM OPCODE ; ; DO A READ/WRITE TYPE I/O REQUEST ; ; CALLING SEQUENCE: ; JSR DOIO ; DB IOCBNO ; DW BUFFER LENGTH ;*_} DB CMD ; DW BUFFER ADDRESS ; DOIO CLC PLA STA RAMLO PLA STA RAMLO+1 LDY #1 LDA (RAMLO),Y BCC DOIO1 STA IAUX,*`}X BCS XTRCB DOIO1 TAX INY LDA (RAMLO),Y STA ILEN,X INY LDA (RAMLO),Y STA ILEN+1,X XTRCB INY LDA (RAMLO),Y STA ICMD,X*a} INY LDA (RAMLO),Y STA IBUF,X INY LDA (RAMLO),Y STA IBUF+1,X TYA CLC ADC RAMLO TAY LDA #0 ADC RAMLO+1 PHA TYA *b}PHA JMP CIOV ;DO I/O REQUEST ; ; IF NO DUP.SYS, INCREMENT DRIVE NO. ; RETRYOS INC DUPSYS+1 LDA DUPSYS+1 AND #$0F CMP #9 *c} BCC RTYOSV BNE GOTO1 CMP RAMDKU BEQ RTYOSV GOTO1 LDA #'1' STA DUPSYS+1 RTYOSV TAX LDA DKTYPE-'1',X BEQ RETRYOS BNE NO*d}WMS ; ; LOAD PROGRAM FUNCTION ; LDFILE JSR LDMEM LDX #$10 JSR TOVECT ;LOAD PROGRAM OR GO TO IT DB $2C ;SKIP THE LDY #1 I*e}NSTRUCTION ; ;************************************* ; ; STANDARD EXIT POINT FOR PROGRAMS ; ;********************************f}****** ; ; RESTORE DOS/DUP INIT VECTOR ; DUPENT LDY #1 SAVERR STY CBSAV BIT STATE BVS GODOS BPL NOWMS JSR CLOS10 JSR SOP*g}EN DB $08 ;WRITE MEM.SAV FILE DB OPEN DW NMSAV BMI NOWMS JSR DOIO DB $10 DW MSLEN DB PUTCHR DW MSBASE NOWMS JSR CLO*h}S10 JSR SOPEN ;GET DUP.SYS INTO MEMORY DB $06 DB 39 DW DUPSYS BMI RETRYOS LDA DOSINI STA INISAV LDA DOSINI+1 STA IN*i}ISAV+1 GODOS JSR CLOSX JMP DOSOS ;THEN START IT UP ; ; SAVE MEMORY SUBROUTINE: WRITE FILE BODY, INIT AND RUN VECTORS ; WDR*j} JSR LDMEM ;LOAD MEM.SAV IF NEED BE WDR1 LDX #$10 ;WRITE TEXT TO DISK FILE JSR CIOV WRERRO BMI SAVERR LDX #LOW[INITAD] JSR*k} WRVEC LDX #LOW[RUNAD] JSR WRVEC BIT STATE BVS GODOS BVC NOWMS ; WRVEC LSR TEMP ;WRITE THIS 6-BYTE VECTOR? BCC RTS2 ;IF*l} NOT, JUST RETURN STX VECTOR LDA INITAD&$FF00,X STA VECTOR+4 INX LDA INITAD&$FF00,X STA VECTOR+5 LDA #HIGH[INITAD] ST*m}A VECTOR+1 STA VECTOR+3 ;(X,A)=MIDDLE WORD STX VECTOR+2 WR6BYT JSR DOIO DB $10 DW 6 DB PUTCHR DW VECTOR BMI WRERRO RTS*n}2 RTS ; ; RUN AT ADDRESS ; TOVECT JMP (VECTOR) ;TO 'RUN AT' ADDRESS ; ; LOAD MEM.SAV IF NEED BE ; LDMEM BIT STATE ;LOAD MEM.S*o}AV? BPL NOLDMS ; LDX #$20 JSR SOPEN DB $04 DB OPEN DW NMSAV BMI NOLDMS ; JSR DOIO DB $20 DW MSLEN DB GETCHR DW MS*p}BASE ; NOLDMS JMP CLOS20 ; NMSAV DB 'D1:MEM.SAV',$9B EC DB 'E:' DUPSYS DB 'D1:DUP.SYS',$9B OPT DB 0 DUPFLAG DB 0 ;DUP RESIDEN*q}T = $80 INISAV DW MDINIT CBSAV DB 0 ;ERROR CODE FROM PROG EXECUTED FNAME DB 0 DS 39 ;ALLOW FOR 40 CHAR DEF DIR ; RESEND DS $*r}300 ;ALLOW FOR THREE FILE BUFFERS DRIVERS DS $800 ;ALLOW 2K FOR RESIDENT CODE DS 39 ;ALLOW FOR 40 CHAR DEF DIR ; RESEND DS $(N; ;====================================================================== ;==================================================.t}==================== ; ; START OF NONRESIDENT PORTION OF DUP.SYS ; DATA DS 80 ;ALLOCATE BUFFER FOR BIT MAP, ETC. DELIM DS 1 .u}PAR2 DS 20 ;PAR* BUFFERS EXPANDED TO 80 BYTES FROM 32 PAR3 DS 80 ; BY BOB PUFF, VERSION 4.5 (PAR2 WAS OK) BOOTBUF DS 384 .v};SPACE FOR 3 BOOT SECTORS TEMPBUF DS 128 ;TEMPORARY BUFFER FOR FILE OPEN DENSITY INIT. ; ; ORG DATA+512 ;USE THIS ORG ONLY I.w}F ABOVE ALLOCS < 512 BYTES ; UNNO DS 1 PTR DS 1 PTRSAV DS 1 IPTR DS 1 IPSAV DS 1 CBYTE DS 1 SECTOR DS 2 CSRC DS 1 CDES DS 1 C.x}PYTYP DS 1 SWPFLG DS 1 RCNT DS 1 SECSIZ DS 2 FNPT DS 1 FNPT2 DS 1 PAR DS 80 ;REAL PARAMETER (LAST) DUPBASE = * DOSSYS DB 'D1.y}:DOS.SYS',$9B ; ; CLOSE (BRUTALLY) ALL IOCBS AND REOPEN SCREEN ; INITIO JSR CIOINV LDX #0 JSR SOPEN ;OPEN SCREEN AS IOCB #.z}0 DB $0C DB OPEN DW EC STX CDTMV3 ;CLEAR TIMER #3 STX CDTMV3+1 LDY #1 LDA #3 STA CDTMF3 ;SET TIMER NOT DONE FLAG J.{}SR SETVBV WAITIM LDA CDTMF3 ;DONE? BNE WAITIM ;NO, CONTINUE LOOPING RTS ; ; DISK UTILITY PROGRAM ENTRY ; DOSOS CLC CLD .|} LDX #-3 HATLP INX INX INX LDA HATABS,X ;REINSTALL E: HANDLER TO CMP #'E' ;AVOID DELETING BASIC PROGRAMS BNE HATLP ;ST.}}ARTED UP BY AUTORUN.SYS LDA #LOW[EDITRV] ;"E:" HANDLER SIMULATORS STA HATABS+1,X LDA #HIGH[EDITRV] ;REMOVED BY BOB PUFF IN.~} 4.5 [Change for scripts] STA HATABS+2,X LDX #$FF STX BRKKEY ;ENABLE BREAK KEY ; LDA #HIGH[MDINIT] STA DOSINI+1 LDA #.}LOW[MDINIT] STA DOSINI ; LDA #2 STA LMARGN ;SET MARGINS LDA #39 STA RMARGN LDA DUPFLAG ORA STATE AND #$C1 CMP #$80 .} BNE NOSWF STA WARMST NOSWF LDA #$40 ORA STATE STA STATE ;ELSE, SAY IT WAS DONE LDA #$80 ORA POKMSK STA POKMSK ;ALLOW.} BREAK INTERRUPTS STA IRQEN JSR INITIO ;CLOSE ALL FILES ; LDA STATE AND #1 BEQ SHMEN JSR ERRXIT ;MEM.SAV ERROR CAN NOW.} BE SHOWN DB 'Error loading MEM.SAV or memory!',$9B,0 ; SHMEN LDA DFUNIT ORA #'0' STA DEFAULT LDX #28 LDY #8 DKSLP LDA #.}' ' STA D1STAT-2,X STA D1STAT-1,X STA D1STAT,X STA D1STAT+1,X CPY RAMDKU BNE CKHCD ;IF NOT RAM DISK LDA #'R' BNE SETU.}NI ; CKHCD LDA HDTAB+8-1,Y BEQ GENDCD ;IF NOT HARD DISK LDA #'H' SETUNI STA D1STAT,X BNE DKUNIN ; GENDCD LDA DKTYPE-1,Y B.}EQ NXTDKS LSR A ;DOUBLE DENSITY? LDA #'S' BCS DKSNGD ;NO, SINGLE LDA #'D' ;YES, DOUBLE DKSNGD STA D1STAT,X LDA DRVDEF-1,.}Y LSR A LDA #'-' BCC DKSSD LDA #'=' DKSSD STA D1STAT+1,X DKUNIN TYA ORA #'0' STA D1STAT-1,X NXTDKS DEX DEX DEX DEX .}DEY BNE DKSLP JSR PRINT DB $7D ;CLEAR SCREEN DB 'MYDOS 4.51 -- copyright 1989,' DC 'W','O','R','D','M','A','R','K' ; DB.} $9B,'DISKS: ' D1STAT DB '1S ' DB '2S ' DB '3S ' DB '4S ' DB '5S ' DB '6S ' DB '7S ' DB '8S' DB 'D: = D' DEFA.}ULT DB '1:',0 LDA #LOW[FNAME] LDX #HIGH[FNAME] JSR PRTMSG ; JSR PRINT DB $9B,$9B DB '1-8.Dir of D1:-D8: *. Dir of D:',$.}9B DB 'A. Disk Directory K. Save Memory',$9B DB 'B. Run Cartridge L. Load Memory',$9B DB 'C. Copy File(s) M. Run at .}Address',$9B DB 'D. Delete File(s) N. Load MEM.SAV',$9B DB 'E. Rename File(s) O. Change Config.',$9B DB 'F. Lock File(s).} P. Set Density',$9B DB 'G. Unlock File(s) Q. Make Directory',$9B DB 'H. Write DOS Files R. Pick Directory',$9B DB 'I..} Initialize Disk S. Set RAMdisk #',$9B DB 'J. Duplicate Disk V. Set Verify Flag',$9B DB ' ',$9B,0 LDY CBSAV BPL MENUSL .}JSR CIOER1 ;IF LOAD ERROR, REPORT IT ; ; SELECT MENU FUNCTION ; MENUSL LDX #$FF TXS INX STX OPT ;OPT=00 IF NO OPTIONS STX.} SWPFLG STX CBSAV ;FOR DIR SCANS, SKIP NO EXTNS. JSR CLOSX ;CLOSE IOCBs 10 AND 20 LDX #$30 JSR CLOS2 ;AND IOCB 30 JSR PR.}INT DB 'Select Item (' DC 'R','E','T','U','R','N' DB ' for menu):',0 LDA #$40 ;FORCE UPPER CASE STA SHFLOK ORA STATE S.}TA STATE ;SAY DUP.SYS IN MEMORY JSR CHRGET CMP #$9B BNE CKITEM JMP SHMEN ; CKFDIR CMP #'1' BCC CKFDD JMP FASTDIR CKFDD .}CMP #'*' BNE BADITM JMP FASTDD ; CKITEM CMP #'9'+1 BCC CKFDIR CMP #'A'+NFUNC BCS BADITM SBC #'A'-1 BCS ITEMV BADITM LD.}A #NFUNC ITEMV ASL A TAY LDA DUPJT,Y STA RAMLO LDA DUPJT+1,Y STA RAMLO+1 JMP PRTMEN ;GO TO MENU EXIT (WITH MESSAGE) ; T.}COMND = * UCOMND = * NSI DB 'No such item!',$9B,0 JMP MENUSL ; DUPJT DW DIRLST-1,STCAR-1 DW CPYFIL-1,DELFIL-1 DW RENFIL-1,.}LKFIL-1 DW ULKFIL-1,WBOOT-1 DW FMTDSK-1,DUPDSK-1 DW SAVFIL-1,LDFIL-1 DW BRUN-1,MEMSAV-1 DW CONFGR-1,CHDISK-1 DW MKDIR-1.},SETDIR-1 DW RAMDRV-1,TCOMND-1 DW UCOMND-1,VERIFY-1 NFUNC = [*-DUPJT]/2 DW NSI-1 EMSAV-1 DW CONFGR-1,CHDISK-1 DW MKDIR-1,T; ; * AND 1-8. FAST DIRECTORY LIST ; FASTDD STA PAR+2 LDA #':' STA PAR+1 BNE DOFDD ; FASTDIR STA PAR+1 LDA #':' STA PAR2}+2 DOFDD LDA #'*' STA PAR+3 STA PAR+4 LDA #'D' STA PAR LDA #$9B STA PAR+5 ;fix the 174 errors in menu [Bob Puff] STA 2}CPYTYP STA DELIM BNE DODIRL ; ; A. DIRECTORY LIST ; DIRLST DB 'Files to list, Destination?',$9B,0 LDA #$9B STA CPYTYP J2}SR GETFN JSR DEFPAR DODIRL LDA #LOW[PAR] LDY #HIGH[PAR] JSR DBUF10 LDX #$10 STX CSRC ;IOCB10 IS SOURCE JSR OPDIR ;OPE2}N IOCB10 AS DIRECTORY ; LDA #HIGH[TEMPBUF+1] STA BUFAD+1 LDA #LOW[TEMPBUF+1] STA BUFAD ; LDA #38 STA BUFLEN LDA #0 ST2}A BUFLEN+1 ; LDX #$00 ;CDES=IOCB00 LDA DELIM BMI CPY1FSP LDA DELIM BMI SGFCPY JSR GETFN2 STY IBUF+$20 STA IBUF+1+$202} SGFCPY LDX #$20 LDA #GETCHR BNE DOCALL ; CPY1FSP LDA #GETREC DOCALL STX CDES JSR COPYF JMP MENUSL ;THEN RETURN TO CMD. L2}INE ; BADRN JSR ERRXIT DB 'Need new file name!',$9B,0 CANTDV JSR ERRXIT DB 'No drive or directories allowed in new name!',$2}9B,0 ; LKMSG DB 'Lock ',0 ULMSG DB 'Unlock ',0 DELMSG DB 'Delete ',0 ; ; D. DELETE FILE(S) ; DELFIL DB 'Delete what file?',$2}9B,0 LDY #LOW[DELMSG] LDX #HIGH[DELMSG] LDA #DELETE BNE DOCMD ; ; F. LOCK FILES ; LKFIL DB 'Lock which file?',$9B,0 LDY2} #LOW[LKMSG] LDX #HIGH[LKMSG] LDA #LOCK BNE DOCMD ;GET FILE NAME THEN LOCK IT ; ; G. UNLOCK FILES ; ULKFIL DB 'Unlock whi2}ch file?',$9B,0 LDY #LOW[ULMSG] LDX #HIGH[ULMSG] LDA #UNLOCK ; DOCMD STY SECSIZ STX SECSIZ+1 PHA JSR GETFN JSR CKDSK 2}LDX OPT CPX #'N' ;IF '/N' THEN DO IT THE EASY WAY BEQ AFTCHK JSR PRINT DB 'Answer ',$27,'Y',$27 DB ' or ',$27,'N',$27,$92}B,0 PLA JSR SETSCN ; RDFN JSR SCNDIR BCS DELX ;IF END OF DIRECTORY LDA SECSIZ LDX SECSIZ+1 JSR PRTMSG LDA #LOW[PAR] L2}DX #HIGH[PAR] JSR PRTMSG JSR PRINT DB '?',0 JSR CHRGET CMP #'Y' BNE NODELT LDX #$20 JSR CIOCL ;DELETE THE FILE THEN N2}ODELT JMP RDFN ; SMPLCMD PHA JSR GETFN ;GET FILE NAME JSR CKDSK ;VERIFY A DISK FILE AFTCHK PLA ISSCMD STA ICMD+$10 LDX #$12}0 JSR CIOCL LDA ICMD+$10 CMP #41 BEQ SETFNJ DELX JMP MENUSL SETFNJ JMP SETFNM JCANTDV JMP CANTDV JBADRN JMP BADRN ; ; E. 2} RENAME FILE(S) ; RENFIL DB 'File to rename, new name?',$9B,0 JSR GETFN JSR CKDSK LDY PTR LDA DELIM CMP #',' BEQ CKNAM22} CMP #' ' BNE JBADRN CKNAM2 INY LDA (FNPTR),Y CMP #':' BEQ JCANTDV CMP #'>' ;check for sparta type BEQ JCANTDV CMP #2}'0' BCC DOREN CMP #'z'+1 BCC CKNAM2 DOREN LDA #RENAME BNE ISSCMD ; ; Q. MAKE A DIRECTORY ; MKDIR DB 'Full directory name2}?',$9B,0 LDX #8 STX IAUX+$10 LDA #34 ;MAKE DIR. COMMAND JMP SMPLCMD ; ; R. SET DIRECTORY ; SETDIR DB 'Directory to be us2}ed as ',$27,'D:',$27,'?',$9B,0 JSR GETFN JSR CKDSK LDY PTR ;DRIVE OR NULL? CPY #4 BCC CPYDNE LDA #41 JMP ISSCMD ; SETF2}NM LDX #0 LDA PTR EOR #4 BEQ ZAPNAM LDY #1 LDA #':' CMP (FNPTR),Y BNE ALLNEW ;IF NOT SUBDIRECTORY FNDEND INX LDY FNAM2}E-1,X BNE FNDEND ;END OF OLD DIR? STA FNAME-1,X ; ALLNEW INY BEQ CPYDNE CMP (FNPTR),Y BNE ALLNEW DEX ;POINT BACK AT ':2}' BEQ CPY1ST ;IF START, NO ':' TO PRESERVE ; CPYNAM INX CPY1ST INY LDA (FNPTR),Y ZAPNAM STA FNAME,X BNE CPYNAM JMP MENUSL2} ; CPYDNE JSR ERRXIT DB 'Invalid directory!',$9B,0 ; ; SINGLE FILE (DEVICE) COPY ; TOERR1 JMP CIOER1 SGCOPY LDX #$10 STX CS2}RC ;SOURCE IS IOCB10 JSR SOPEN DB 4 ;INPUT DB OPEN ;OPEN FUNCTION DW PAR ;INPUT DEVICE NAM BMI TOERR1 JMP SGFCPY ; ; C.2} COPY FILES ; DUPFIL = * CPYFIL DB 'File source, destination?',$9B,0 LDA #' ' STA PAR3+2 ;DEFINE CHAR 3 OF DEVICE NAME LD2}A #$9B STA CPYTYP JSR GETFN ;GET SOURCE FILE NAME ; LDA #HIGH[DUPEND] STA BUFAD+1 LDA #LOW[DUPEND] STA BUFAD ; LDA MEM2}TOP SEC SBC #LOW[DUPEND] STA BUFLEN LDA MEMTOP+1 SBC #HIGH[DUPEND] STA BUFLEN+1 ; JSR DEFPAR LDA DELIM BMI SFNAME J2}SR GETFN2 LDA #0 SFNAME STA SWPFLG ASL WARMST LDA FNPTR+1 STA IBUF+1+$20 LDA FNPTR STA IBUF+$20 LDA PAR ;DISK DEVICE? 2} CMP #'D' BNE SGCOPY LDA #LOW[PAR] LDY #HIGH[PAR] JSR DBUF10 ; LDA #'?' LDY #11 QQQ STA PAR2-1,Y DEY BNE QQQ ; JSR C2}WFSD LDX #$10 JSR OPDIR ;OPEN IOCB10 AS DIRECTORY ; LDY #$FF CPSCL1 INY LDA (FNPTR),Y STA PAR3,Y BNE CPSCL1 CPSCL2 DEY 2} LDA (FNPTR),Y CMP #'>' ;account for sparta type BEQ CPSCL3 CMP #':' BNE CPSCL2 CPSCL3 INY STY FNPT2 LDA (FNPTR),Y BE2}Q OPINP ; LDX #0 ;SCAN -PAR- STARTING AT 1-ST BYTE MVMSK LDA (FNPTR),Y BMI WCOPYB ;1 FILESPEC COPY?? CMP #'*' BEQ MVNML 2}CMP #'.' BCC WCOPYB BNE DOSTOR LDA #' ' DEY DOSTOR STA PAR2,X INY MVNML INX CPX #8 BCC MVMSK SKPPRD INY MVEXT LDA (FNP2}TR),Y BEQ WCOPYB CMP #'.' BEQ SKPPRD ;IF A PERIOD, SKIP OVER IT CMP #'*' BEQ OPINP CMP #' ' BEQ WCOPYB CMP #',' BEQ 2}WCOPYB CMP #$9B BEQ WCOPYB INY SAVBLK STA PAR2,X INX CPX #11 BCC MVEXT BCS OPINP ; WCOPY JSR CWFSD OPINP JSR SCNDIR B2}IT CBYTE BMI OPINP BCC WCNEXT JMP MENUSL ; WCOPYB LDA #' ' BNE SAVBLK WCNEXT LDA #HIGH[PAR3] STA IBUF+$30+1 LDA #LOW[PA2}R3] STA IBUF+$30 ; LDX #0 LDY FNPT2 WCNBLD LDA PAR2,X BEQ TERMX CMP #'?' BNE STWCC LDA DATA+2,X STWCC STA PAR3,Y CMP 2}#' ' BEQ OVWRTC INY OVWRTC INX CPX #8 BCC WCNBLD LDA #'.' STA PAR3,Y INY WCEBLD LDA PAR2,X BEQ TERMX CMP #'?' BNE S2}TWCEC LDA DATA+2,X STWCEC STA PAR3,Y CMP #' ' BEQ OVWRTE INY OVWRTE INX CPX #11 BCC WCEBLD TERMX LDA #'.' CMP PAR3-1,Y2} BNE NOTOVP DEY NOTOVP LDA #$9B LDX OPT CPX #'Q' BNE NOQUERY LDA #'?' NOQUERY STA PAR3,Y LDA #0 STA PAR3+1,Y ; LDA C2}PYTYP BNE DOONE LDA #LOW[PAR] LDX #HIGH[PAR] JSR PRTMSG JSR PRINT DB '-->',0 LDA #LOW[PAR3] LDX #HIGH[PAR3] JSR PRTM2}SG LDA OPT CMP #'Q' BNE DOONE JSR CHRGET CMP #'Y' BNE SKPCOP DOONE LDA IAUX+5+$10 STA IAUX+5+$20 LDX #$20 STX CSRC 2}LDA #4 STA IAUX,X LDA #LOW[PAR] LDY #HIGH[PAR] JSR DEFBUF LDA #OPEN JSR SCMD ;OPEN THE SOURCE FILE BMI CPYERR ; LDX 2}#7 CKFDOS LDA CKDTST-1,X ;File name = DOS.SYS? CMP PAR3+2,X BNE NOXDOS ;No, handle it normally then DEX BNE CKFDOS ; ; 2}COPYING DOS.SYS, SET UP FOR RENAME AND LOAD BOOT SECTORS ; LDA PAR3+1 STA DOSRNM+1 ;Stash the unit number in the rename buf2}fer STA DOSSYS+1 LDA #$60 ;Change destination name to diamond-OS STA PAR3+3 ; CLC ;READ BOOT SECTORS JSR DOBOOT ;DO 2}BOOT I/O ; ; THIS REALLY COPIES THE FILE . . . ; NOXDOS LDA #HIGH[PAR3] STA IBUF+$30+1 LDA #LOW[PAR3] STA IBUF+$30 ; LDX2} #8 ;IOCB $30 set up for writing STX IAUX+$30 LDX #$30 STX CDES LDA #GETCHR JSR COPYF ;COPY FILE ; LDA DOSRNM+1 ;NEED 2}TO RENAME DOS.SYS? BEQ SKPCOP ; ; WRITE THE BOOT SECTORS OUT TO THE DESTINATION AND RENAME BACK TO DOS.SYS ; JSR FIXUPDOS 2};FIX BOOT SECTORS, WRITE THEM, AND RENAME FILE LDA #0 ;CLEAR RENAME FLAG STA DOSRNM+1 ; SKPCOP LDA CPYTYP BNE TOEXIT JMP2} WCOPY TOEXIT JMP MENUSL CPYERR JMP CIOER1 ILE LDA #0 ;CLEAR RENAME FLAG STA DOSRNM+1 ; SKPCOP LDA CPYTYP BNE TOEXIT JMP0+; ; I. FORMAT A DISK ; FMTDSK DB 'Disk to FORMAT:',0 JSR GETDN ;GET DRIVE NUMBER OR NAME JSR DEFPAR ; LDA #HIGH[PAR] STA6} IBUF+$10+1 LDA #LOW[PAR] STA IBUF+$10 ; LDY #1 LDA (FNPTR),Y STA FMTDVN ; ; MAKE SURE ABOUT DRIVE NUMBER ; JSR PRINT 6}DB '(Press [A] for Enhanced Dns)',$9B DB 'Type [Y] to Format Drive ' FMTDVN DB '0:',0 ; JSR CHRGET CMP #'A' BEQ FMT1050 6}EOR #'Y' BNE WBX DOFMT STA IAUX+$10 LDA #0 LDX OPT ;REAL FORMAT? CPX #'N' BNE RELFMT ROR A RELFMT STA IAUX+1+$10 ; LDA6} #FORMAT STA ICMD+$10 LDX #$10 JSR CIOV ;DO FORMAT OF DISK BPL WBX WBERR JMP CIOER1 ;IF ERROR, SAY SO! WBX DEY BEQ ALFMT6}D JSR ERRXIT DC 'W','A','R','N','I','N','G' DB ': Bad sectors on disk!',$9B,0 ALFMTD JMP MENUSL ; FMT1050 LDA #1 BNE DOFM6}T ; ; H. WRITE DOS/DUP TO DISK ; DUPFNM DB 'D1:DUP.SYS',$9B WBOOT DB 'Drive to write DOS files to?',0 JSR GETDN LDA DUPSYS6}+1 PHA LDA #'1' STA DUPSYS+1 STA NMSAV+1 LDY #1 LDA (FNPTR),Y CMP #':' BNE CANWB LDA DEFAULT CANWB STA DOSSYS+1 STA6} DUPFNM+1 ; DEY ;SET UP INITIAL VALUES OF PARMS. STY OPT LDA #$80 STA STATE ; LDA #LOW[DOSSYS] LDY #HIGH[DOSSYS] JSR 6}DBUF10 LDA #8 ;OPEN OUTPUT=WRITE DOS.SYS STA IAUX+$10 JSR ANYDEN ;OPEN AND WRITE DOS.SYS (ANY DENSITY) JSR CLOS10 PLA S6}TA NMSAV+1 STA DUPSYS+1 ; ; **** WRITE DUP.SYS HERE **** ; LDY #$70 LDA #LOW[DUPBASE] LDX #HIGH[DUPBASE] JSR D2B8A ; LD6}A #HIGH[DUPFNM] STA IBUF+$10+1 LDA #LOW[DUPFNM] STA IBUF+$10 LDA #HIGH[DUPEND-1] STA HDBUF+3 LDA #LOW[DUPEND-1] STA HD6}BUF+2 LDA #HIGH[DUPLEN] STA HDBUF+5 LDA #LOW[DUPLEN] STA HDBUF+4 ; LDA #0 STA TEMP ;CLEAR 'RUN' FLAG JMP WRDUP ;WRIT6}E DUP.SYS ; ; J. DUPLICATE A DISK ; DUPDSK DB 'Source, Destination (Sectors)?',$9B,0 JSR GETDN LDY #1 LDA (FNPTR),Y AND 6}#$0F ;GET DRIVE NUMBER STA CSRC STA CDES LDA DELIM ;IF SINGLE DRIVE DUP. CMP #'(' BEQ SETSSZ ;GO SET SECTOR SIZE JSR GE6}TDN2 ;ELSE, GET SECOND DRIVE NAME LDY #1 LDA (FNPTR),Y AND #$0F STA CDES CMP CSRC ;SAME DRIVE? BNE SETSSZ ;YES, SINGLE 6}DRIVE DUP. LDX #$9B STX SWPFLG SETSSZ TAX LDY CSRC LDA SWPFLG ORA #$40 ;SET DUP-DISK FLAG STA SWPFLG BMI DODKDP JSR P6}RINT DB 'Insert both disks, type ' DC 'R','E','T','U','R','N' DB 0 JSR CHRGET ; DODKDP JSR CWFSD LDA CSRC ;POINT TO SOUR6}CE DRIVE JSR GETDEN ;IDENTIFY DENSITY OF SOURCE DISKETTE LDY CDES ;ELSE, TWO DRIVE DUP. LDX CSRC LDA DKTYPE-1,X CMP DKTY6}PE-1,Y BEQ SAME STY UNNO JSR SETDEN LDY CDES LDX CSRC LDA DKTYPE-1,X CMP DKTYPE-1,Y BEQ SAME JSR ERRXIT DB 'Drives 6}not compatible!',$9B,0 SAME ASL WARMST LSR A STA SECSIZ+1 ROR A STA SECSIZ ;SET SECTOR SIZE (128 OR 256) STX DUNIT ;READ6} SOURCE VTOC ; LDA DELIM PHA LDA #$FF TAX INIBMP STA DATA+128,X STA DATA+256,X DEX BNE INIBMP PLA ;BOOT COPY? CMP #6}'(' BEQ BLDVTOC ;YES, BUILD IMAGINARY VTOC CMP #$9B BEQ RDVTOC ;NO, DOS COPY OOPS JSR ERRXIT ;ELSE, ERROR DB 'Invalid opt6}ions!',$9B,0 BLDVTOC JSR GETNUM CPY #'-' BNE OOPS STA DATA+3 STX DATA+4 JSR GETNUM CPY #')' BNE OOPS STA DATA+1 STX 6}DATA+2 LDY #0 STY PTR STY DATA+6 STY DATA+5 ; LDA #HIGH[DATA+10] STA BUFAD+1 LDA #LOW[DATA+10] STA BUFAD ; LDA #$FE 6}D26BB LDX DATA+6 CPX DATA+4 BNE D26CB LDX DATA+5 CPX DATA+3 BCS D26D2 D26CB SEC ROL A JSR NXTSCT BNE D26BB ; D26D2 LD6}X DATA+2 CPX DATA+6 BCC D26EA BNE D26E4 LDX DATA+1 CPX DATA+5 BCC D26EA D26E4 ASL A JSR NXTSCT BNE D26D2 ; D26EA SEC 6} ROL A BCS D26EA STA (BUFAD),Y ; RDVTOC SEC LDA MEMTOP SBC SECSIZ STA BUFLEN LDA MEMTOP+1 SBC SECSIZ+1 STA BUFLEN+1 ;6} LDA BUFLEN CMP #LOW[DUPEND] LDA BUFLEN+1 SBC #HIGH[DUPEND] BCS ENUF JSR ERRXIT DB 'Not enough memory!',$9B,0 ; NXTSCT6} BCS D272E STA (BUFAD),Y LDA #$FE INC BUFAD BNE D272E INC BUFAD+1 D272E INC DATA+5 BNE D2736 INC DATA+6 D2736 RTS ; EN6}UF LDA PTR BEQ SKRDVT ;IF POS, SKIP READING VTOC LDA #LOW[360] LDX #HIGH[360] STA DAUX STX DAUX+1 LDA #LOW[DATA] LDX #6}HIGH[DATA] STA DBUF STX DBUF+1 JSR RSEC1 BPL NOERFD JMP CIOER1 NOERFD CLC LDA DATA+1 ADC #12 ;ADD IN THE BOOT, MAP AN6}D DIR SECTORS STA DATA+1 BCC CK2BIT ;THEN TAKE CARE OF SECOND BIT MAP IF NEC. INC DATA+2 ;ELSE, BUMP UPPER BYTE CK2BIT L6}DA DATA CMP #4 BCC SKRDVT ;IF SINGLE SECTOR, SKIP READING SECOND INC DATA+1 CLC LDA DBUF ADC DLEN STA DBUF LDA DBUF+6}1 ADC DLEN+1 STA DBUF+1 DEC DAUX JSR RSEC1 ; SKRDVT LDA #0 STA DAUX+1 LDA #1 STA DAUX LDA DATA+10 STA CBYTE LDA #8 6} STA IPTR LDA #HIGH[DATA+10] STA VECTOR+1 LDA #LOW[DATA+10] STA VECTOR ; DORD LDA VECTOR STA PTRSAV LDA VECTOR+1 STA P6}TR LDA IPTR STA IPSAV LDA CBYTE STA CBSAV LDA DAUX STA SECTOR LDA DAUX+1 STA SECTOR+1 LDA #0 STA CPYTYP ;SET OPERAT6}ION TO 'READ' LRS LDA #HIGH[DUPEND] STA DBUF+1 LDA #LOW[DUPEND] STA DBUF LRS1 ASL CBYTE DEC IPTR BNE CBIT INC VECTOR B6}NE PAGE1 INC VECTOR+1 PAGE1 LDY #0 LDA (VECTOR),Y STA CBYTE LDX #8 STX IPTR CBIT BIT CBYTE BMI ASPT LDA CPYTYP ASL A 6};CY=0, READ; CY=1, WRITE LDA CSRC BCC RSECIN ;ACC=DRIVE # LDA CDES RSECIN JSR SECTIO ;READ OR WRITE IOD CLC LDA DBUF ADC6} SECSIZ STA DBUF LDA DBUF+1 ADC SECSIZ+1 STA DBUF+1 ASPT LDA DAUX CMP DATA+1 LDA DAUX+1 SBC DATA+2 BCC ASPN ; LDA CP6}YTYP ;END OF DRIVE BPL STDD2 ;IF READ, DO WRITE JMP MENUSL ;IF WRITE, THEN DONE! ; ASPN INC DAUX BNE ASPX INC DAUX+1 ASPX6} LDA BUFLEN ;ELSE, END OF THE BUFFER? CMP DBUF LDA BUFLEN+1 SBC DBUF+1 BCS LRS1 ;NO, GET NEXT SECTOR ; LDA CPYTYP BPL S6}TDD2 ;IF WRITE, DO NEXT READ JSR CWFSD JMP DORD ; STDD2 BIT SWPFLG BPL CKFORM JSR PRINT IDD DB 'Insert DESTINATION disk, 6}press ' DC 'R','E','T','U','R','N' DB 0 JSR CHRGET CKFORM LDA #'N' CMP OPT BEQ NOFORM STA OPT LDX #$20 ;IF FORMAT REQ.6}, DO IT LDA #LOW[DOSSYS] LDY #HIGH[DOSSYS] JSR DEFBUF LDA #FORMAT STA ICMD+$20 LDA CDES ORA #'0' ;CONVERT DRIVE NO. TO6} ASCII STA DOSSYS+1 JSR CIOCL NOFORM DEC CPYTYP ;THEN, MAKE A WRITE LDA PTRSAV STA VECTOR LDA PTR STA VECTOR+1 LDA SEC6}TOR STA DAUX LDA SECTOR+1 STA DAUX+1 LDA IPSAV STA IPTR LDA CBSAV STA CBYTE JMP LRS R LDA PTR STA VECTOR+1 LDA SEC4\; ; K. SAVE FILE COMMAND ; SAVFIL DB 'SAVE:filename,start,end(,init(,run))',$9B,0 JSR GETFN STY IBUF+$10 STA IBUF+1+$10 :}LDA OPT PHA JSR GETNO2 CPX #HIGH[DUPEND] LDY #$70 BCS DSLMFG LDY #$60 ;FORCE MEM.SAV TO MEMORY BEFORE SAVING IMAGE DSLM:}FG JSR D2B8A JSR GETNO2 STA HDBUF+2 STX HDBUF+3 SEC SBC HDBUF STA HDBUF+4 TXA SBC HDBUF+1 BPL ADDOK JSR ERRXIT DB ;}'Invalid START-END range!',$9B,0 ADDOK STA HDBUF+5 INC HDBUF+4 BNE INCOK INC HDBUF+5 INCOK LDA #0 CPY #CR BEQ NINTAD JS;}R GETNO2 STA INITAD STX INITAD+1 ORA INITAD+1 BEQ NINTAD LDA #1 ;SET 'GOT INIT' FLAG NINTAD STA TEMP CPY #CR BEQ NRUNA;}D JSR GETNO2 STA RUNAD STX RUNAD+1 ORA RUNAD+1 BEQ NRUNAD INC TEMP INC TEMP ;SET 'GOT RUN' FLAG NRUNAD PLA WRDUP LDY #;}0 STY OPT DEY STY VECTOR STY VECTOR+1 ; ; OPEN THE PROGRAM FILE ; LDY #8 CMP #'A' BNE OPTOK1 DEC OPT INY OPTOK1 STY ;}IAUX+$10 LDX #$10 JSR ANYDEN ;OPEN FILE 'OUTPUT/ANY DENSITY' BMI KIOERR LDA OPT BEQ FULHDR ;IF NO 'APPEND' JSR DOIO ;WR;}ITE SHORT HEADER DB $10 DW 4 DB PUTCHR DW VECTOR+2 BMI KIOERR KEXIT LDA HDBUF+4 STA ILEN+$10 LDA HDBUF+5 STA ILEN+1+$;}10 LDA HDBUF STA IBUF+$10 LDA HDBUF+1 STA IBUF+1+$10 BIT STATE BMI KMSAV JMP WDR1 KMSAV JMP WDR ; FULHDR JSR WR6BYT B;}PL KEXIT KIOERR JMP CIOER1 ; D2B8A STA HDBUF STX HDBUF+1 STY STATE RTS ; ; N. LOAD PROGRAM INTO MEM.SAV ; MEMSAV DB 'Load;} MEM.SAV from what file?',$9B,0 LDA STATE ORA #$80 ;TURN ON MEM.SAV FLAG BMI LOADIT TOMEN JMP MENUSL ; ; L. LOAD USER FI; }LE FUNCTION ; BDLDFL LDY #180 BLOWUP JMP CIOER1 ; LDFIL DB 'Load from what file?',$9B,0 LDA STATE AND #$7F ;TURN OFF MEM.S; }AV FLAG LOADIT STA STATE JSR GETFN STY IBUF+$10 STA IBUF+1+$10 LDX DATA+3 ;JUST A CR? BEQ TOMEN LDA #4 STA IAUX+$10 ; }LDX #$10 JSR ANYDEN JSR DOIO DB $10 DW 2 DB GETCHR DW DATA BMI BLOWUP LDA DATA AND DATA+1 CMP #$FF BNE BDLDFL LDA; } DATA+3 BEQ TOMEN LDA OPT EOR #'N' BEQ GOTN LDA #0 STA WARMST LDA #3 GOTN EOR #7 STA IAUX+$10 LDA #39 STA ICMD+$10 ; } LDA #LOW[CIOV] LDX #HIGH[CIOV] BNE BRUN1 ; ; B. RUN CARTRIDGE ; STCAR DB 0 LDA $BFFD EOR #$AA STA $BFFD CMP $BFFD BN;}E NORAM ;IF ADDRESS SPACE IS NOT RAM EOR #$AA STA $BFFD ;IF RAM, NO CARTRIDGE NOCART JSR ERRXIT DB 'NO CARTRIDGE!',$9B,0;} ; NORAM LDX $BFFC BNE NOCART ;IF NOT ATARI CARTRIDGE LDA CARTST LDX CARTST+1 BRUN1 STA VECTOR STX VECTOR+1 LDA INISAV ;} STA DOSINI LDA INISAV+1 STA DOSINI+1 LDA STATE AND #$BF STA STATE JMP LDFILE ; ; M. RUN AT ADDRESS ; BRUN DB 'Run fro;}m what address?',0 JSR GETLIN LDA (FNPTR),Y CMP #$9B ;NO ADDRESS? BEQ BRUN2 ;IF SO, ABORT JSR GETNO2 CPY #$9B BNE BRUN;}2 LDY #0 STY WARMST BEQ BRUN1 BRUN2 JSR ERRXIT DB 'Address must be 1-4 hex digits!',$9B,0 JSR GETNO2 CPY #$9B BNE BRUN8^; ; P. CHANGE DISK FORMAT ; CHDISK DB 'Drive, new density:',0 JSR GETDN ;GET DRIVE NO. LDA DELIM CMP #$9B ;DRIVE NUMBER O?}NLY? BNE CHDSK2 ;IF SO, CHANGE DEFAULT BADPCMD JSR ERRXIT DB 'Drive unchanged.',$9B,0 CHDSK2 LDY PTR LDA (FNPTR),Y TAX L?}DY #1 LDA (FNPTR),Y CMP #'9' BCS BADPCMD SBC #'1'-1 BCC BADPCMD TAY INY STY UNNO LDA #1 CPX #'S' BEQ TOSGL CPX #'?}D' BNE BADPCMD ASL A TOSGL STA DKTYPE-1,Y JSR DOFSIN JMP SHMEN ;THEN SHOW CHANGED MENU ; ; O. CONFIGURE SYSTEM OR DISK D?}RIVE ; CKBANKS SEI ;was CHKBANKS LDY #0 ;This is BOB code... STY $D40E ;uncommented as STY $D20E ;per usual... LDA $?}D301 PHA ;We validate the memory mapping ability LDX #$FF ;of the box we are running in? CKBL1 STY $D301 ;[Don't really?} understand this, but LDA $4000 ; thats OK, for now, ChasM] STA MAPBUF,Y ;[Bob Puff] STX $4000 TXA sta MAPBUF+256,Y IN?}Y BNE CKBL1 DEX STX $D301 STX 0 STX $4000 STX $8000 STX $C000 LDX #0 CKBL2 sty $D301 lda $4000 cmp #$FF bne CKBNO?}T inx stx $4000 txa CKBNOT sta MAPBUF+256,Y iny bne CKBL2 stx RDKLMT ; ldx #1 CKBL8 txa ldy #$FF CKBL6 cmp MAPBUF+256?},Y beq CKBFO dey cpy #$FF bne CKBL6 ;;;;;; nop ;was a DEY CKBL9 sty $D301 lda MAPBUF,Y sta $4000 dey cpy #$FF bne?} CKBL9 pla sta $D301 lda #$C0 sta $D40E lda $10 sta $D20E cli rts ; CKBFO tya sta MAPAGE-1,X inx cpx #65 bcc C?}KBL8 ldy #$FE bne CKBL9 ; SPCPORT JSR PRINT ;Handle non-standard port addresses DB 'Control Address(HEX)?',0 JSR GETLIN ?} JSR GETNO2 TAY ORA VECTOR+1 BNE SAVADR beq RAMDSU ;If < $0100, ask again! jmp SAVADR ;Stash the specified address ; ;? } Test for RAMdisk, and configure it ; GETRDK jsr PRINT db 'RAM disk present?',0 jsr CHRGET ldy #$FF cmp #'N' bne RAMDSU?!} jmp NOFAST ; RAMDSU jsr PRINT db '[A]xlon, [X]E or [C]ustom RAMdisk?',0 jsr CHRGET cmp #'C' beq SPCPORT ldy #LOW[$D301?"}] ldx #HIGH[$D301] cmp #'A' bne SAVADR ldy #LOW[$CFFF] ldx #HIGH[$CFFF] cmp #'X' bne RAMDSU ;Keep on trying! SAVADR ?#}sty RDAD1 sty RDAD2 sty RDAD3 stx RDAD1+1 stx RDAD2+1 stx RDAD3+1 cmp #'X' bne OKP0 jsr CKBANKS lda RDKLMT bne OKP1?$} jsr PRINT db 'No extra memory available!',$9B,0 ldy #0 jmp NOFAST OKP0 jmp RMDSU2 ; OKP1 ldx #0 stx NMLMAP stx FR0+1 ?%}asl a asl a rol FR0+1 asl a rol FR0+1 asl a sta FR0 rol FR0+1 jsr IFP jsr FASCII jsr PRINT db 'Use default config ?&}for ',0 ldy #0 OKP2 lda (INBUFF),Y bmi OKP3 iny bne OKP2 OKP3 and #$7F sta (INBUFF),Y iny lda #0 sta (INBUFF),Y lda ?'}INBUFF ldx INBUFF+1 jsr PRTMSG jsr PRINT db 'K?',0 jsr CHRGET cmp #'N' beq RMDSU2 jmp DVNOQ ; RMDSU2 JSR PRINT DB 'S?(}ize(K)?',0 JSR GETLIN JSR GETNUM LSR VECTOR+1 ROR A LSR VECTOR+1 ROR A LSR VECTOR+1 ROR A LSR VECTOR+1 ROR A BNE S?)}AVRDS LDA #4 SAVRDS STA RDKLMT ; GETSEQN JSR PRINT DB 'Page sequence?',0 JSR GETLIN JSR GETNO2 CPY #CR BNE FSNUM BEQ R?*}SEQ DVNOQ JSR PRINT DB 'RAM disk drive no?',0 GETRDRV JSR CHRGET LDY #9 ;ASSUME 9 CMP #'0' BCC NOFAST ;IF DIGIT, CHANGE?+} RAMDISK CODE CMP #'9' BCS NOFAST AND #$0F TAY NOFAST STY RAMDKU ;SET RAMDISK UNIT NO. RTS ; RSEQ TAY LDX PGMAP,Y STX?,} NMLMAP CPY #3 BCS CPAXSQ LDA SQMAP,Y LDX #0 CPY0 ROL A ROL A PHA ROL A ROL A ROL A AND #$0C TAY CPY1 LDA SQTAB,Y ?-} STA MAPAGE,X INX INY TXA AND #3 BNE CPY1 PLA CPX #16 BNE CPY0 CPSEQ LDA SQTAB,X STA MAPAGE,X INX CPX #64 BNE CPS?.}EQ BEQ DVNOQ ; CPAXSQ LDX #64 AXSQL DEX TXA STA MAPAGE,X BNE AXSQL BEQ DVNOQ ; FSNUM LDX #0 PHA TXA FSNCL STA DATA+256?/},X INX BNE FSNCL PLA FSLP1 STX UNNO CPY #CR BEQ TONML STA DATA+256-64,X TAX LDA DATA+256,X BNE BADSEQ DEC DATA+256,?0}X LDY PTR LDA (FNPTR),Y CMP #CR BNE FSLP4 JSR GETLIN FSLP4 JSR GETNO2 LDX UNNO INX CPX #64 BNE FSLP1 TONML CPX RDKLM?1}T BNE WRONG STA NMLMAP UPDLP1 DEX LDA DATA+256-64,X STA MAPAGE,X TXA BNE UPDLP1 JMP DVNOQ BADSEQ JSR PRINT DB 'Duplic?2}ated sequence number!',$9B,0 JMP GETSEQN ; WRONG JSR PRINT DB 'Wrong number of entries!',$9B,0 JMP GETSEQN ; PGMAP DB $00,?3}$00,$00,$FF,$FF,$FF SQMAP DB $9C,$D8,$4B,$FF,$FF,$00 ; SQTAB DB $A3,$A7,$AB,$AF DB $C3,$C7,$CB,$CF DB $E3,$E7,$EB,$EF DB $?4}83,$87,$8B,$8F ; DB $A1,$A5,$A9,$AD DB $C1,$C5,$C9,$CD DB $E1,$E5,$E9,$ED DB $81,$85,$89,$8D ; DB $A2,$A6,$AA,$AE DB $C?5}2,$C6,$CA,$CE DB $E2,$E6,$EA,$EE DB $82,$86,$8A,$8E ; DB $A0,$A4,$A8,$AC DB $C0,$C4,$C8,$CC DB $E0,$E4,$E8,$EC DB $80,$?6}84,$88,$8C ; CONSYS JSR PRINT DB 'Verify WRITEs?',0 JSR DOVRFY JSR PRINT DB 'Number of File Buffers?',0 JSR GETLIN JSR ?7}GETNUM TAX BEQ SKPFCT CMP #17 BCS SKPFCT STA FILES ;SET NUMBER OF FILES (0-16) SKPFCT JSR GETRDK JSR MDINIT ;REINITIALI?8}ZE DOS3 JMP DOSOS ; ZAPDRV LDA #$D2 DB $2C ;SKIP 2 BYTES SET52 LDA #$52 LDY UNNO STA DRVDEF-1,Y JSR CLRHDS CONXIT JMP ME?9}NUSL ; CONFGR DB 'Drive number or ' DC 'R','E','T','U','R','N' DB ':',0 JSR CHRGET ;GET DRIVE NUMBER CMP #$9B ;IF RETURN,?:} GO TO SYSTEM CONFIGURATION BNE CONDRIV JMP CONSYS CONDRIV CMP #'9' BCC SAVDVN TOBADP JMP BADPCMD SAVDVN SBC #'1'-1 BCC T?;}OBADP TAY INY STY UNNO LDA #0 ;THEN ZERO CONFIGURATION BYTE STA DRVDEF-1,Y ; JSR PRINT DB 'Remove drive?',0 JSR CHRGE?<}T CMP #'Y' BEQ ZAPDRV JSR PRINT DB 'Is drive configurable?',0 JSR CHRGET CMP #'Y' ;IF NO, SET TO $52 AND EXIT BNE SET5?=}2 JSR PRINT DB 'High capacity drive?',0 JSR CHRGET CMP #'Y' BEQ GETHCD JSR PRINT DB 'Is drive double sided?',0 JSR CH?>}RGET CMP #'Y' BNE SETSS LDA #$01 JSR ORDRV SETSS JSR PRINT DB 'Tracks/side?',0 JSR GETLIN JSR GETNUM CMP #35 BEQ SET??}35 TAY LDA #$30 CPY #77 BEQ SETTKS LDA #$20 CPY #80 BEQ SETTKS LDA #$10 CPY #40 BNE SETSS SETTKS JSR ORDRV SET35 JS?@}R PRINT DB 'Step rate?',0 JSR CHRGET CMP #'4' BCS SET35 SBC #'0'-1 BCC SET35 ASL A JSR ORDRV JSR CLRHDS JMP MENUSL ?A}; GETHCD JSR PRINT DB 'Drive size (in sectors)?',0 JSR GETLIN JSR GETNUM CPX #0 BEQ GETHCD ;INVALID SIZE PHA LDY UNNO ?B} LDA #$12 STA DRVDEF-1,Y LDA #2 STA DKTYPE-1,Y PLA JSR SETHDS JMP MENUSL ; ; S. Set RAMdisk Drive Number ; RAMDRV DB ?C}'RAM disk drive no?',0 JSR GETRDRV JMP MENUSL ; ; V. Set Verify Flag ON or OFF ; VERIFY DB 'Verify WRITEs?',0 JSR DOVRFY?D} JMP MENUSL ; DOVRFY JSR CHRGET LDX #$57 ;ASSUME YES! CMP #'N' BNE DOVFY LDX #$50 DOVFY STX WRCMD ;SAVE THE WRITE COMMAN?E}D IN DOS RTS ; ORDRV LDY UNNO ORA DRVDEF-1,Y STA DRVDEF-1,Y RTS ; CLRHDS LDX #0 TXA SETHDS LDY UNNO STA HDTAB-1,Y TXA ?F} STA HDTAB+8-1,Y JMP DOFSIN O ORA DRVDEF-1,Y STA DRVDEF-1,Y RTS ; CLRHDS LDX #0 TXA SETHDS LDY UNNO STA HDTAB-1,Y TXA <; ; PUT A SINGLE CHARACTER ON THE SCREEN ; CHRPUT LDX #PUTCHR STX ICMD LDX #0 STX ILEN STX ILEN+1 JMP CIOV ; ; PUT MESSACH}GE TO THE SCREEN ; PRTMSG STA RAMLO STX RAMLO+1 PRTNXT LDX #0 LDA (RAMLO,X) BEQ PRTXIT JSR CHRPUT PRTENT INC RAMLO BNE PCI}RTNXT INC RAMLO+1 BNE PRTNXT PRTXIT RTS ; ; PRINT AN IN-LINE STRING ; PRINT PLA STA RAMLO PLA STA RAMLO+1 PRTMEN JSR PRTCJ}ENT LDA RAMLO+1 PHA LDA RAMLO PHA RTS ; ; READ A BYTE FROM THE KEYBOARD ; CHRGET JSR XE424 ;FETCH THE BYTE CPY #0 BMI CK}KILLRD ;IF BREAK OR EOF, ABORT COMMAND CMP #'z'+1 ;> LOWER CASE Z? BCS NCHGCS CMP #'a' ;< LOWER CASE A? BCC NCHGCS SBC #CL}$20 ;CONVERT TO UPPER CASE NCHGCS PHA ;SAVE IT CMP #$9B BEQ CHRXIT ;IF EOL, ECHO IT JSR CHRPUT ;ELSE, ECHO IT LDA #$9B ;CM}FOLLOWED BY EOL CHRXIT JSR CHRPUT PLA ;RESTORE FOR PROGRAM RTS ;THEN EXIT KILLRD JSR CHRPUT ;MOVE TO NEXT LINE AND JMP MCN}ENUSL ;EXIT WITHOUT RETURN TO COMMAND ; XE424 ldx #$70 ;Get a character from the keyboard [Bob Puff] jsr CLOS2 ;Close IOCBCO} $70 ; jsr SOPEN ;Open IOCB #$70 for keyboard input db 4 db OPEN dw KDEV ; jsr DOIO ;get a character db $70 ;IOCB $7CP}0 dw 0 ;Buffer length (0=return 1 byte in ACC) db GETCHR dw 0 ;Buffer address (unused) pha ;save the character for a CQ}sec. ; ldx #$70 jsr CLOS2 ;Close IOCB $70 again ; pla ;get character back rts ;that's all, folks! ; KDEV db 'K:',$9BCR} ;Keyboard handler addr. ; CLOSE7 jsr DOIO ;close IOCB #7 db $70 dw 0 db $0C dw 0 rts ; ; RAW SECTOR READ/WRITE FUNCTIOCS}NS ; RSEC1 LDA CSRC RSEC2 CLC ; SECTIO STA DUNIT LDX SECSIZ+1 INX STX SECDAT BOOT1 LDX #3 STX RCNT CLD1 LDX SECDAT PHP CT}JSR DKIO2 BPL DRTS CMP #$80 BEQ TOERR2 PLP DEC RCNT BPL CLD1 PHP TOERR2 PLP JMP CIOER1 ; DRTS PLP RTS ; ; BOOT SECTCU}OR I/O ROUTINE (USED TO COPY DOS.SYS) ; DOBOOT LDA #HIGH[BOOTBUF-128] STA DBUF+1 LDA #LOW[BOOTBUF-128] STA DBUF ;INITIALCV}IZE THE BUFFER ADDRESS LDA #0 ;START WITH SECTOR #1 STA DAUX ; JSR BOOTIO ; JSR BOOTIO ;2 CALLS, THEN FALL THROUGH (TRACW}NSFER 3 SECTORS) ; BOOTIO JSR STEPBP INY STY DAUX JMP BOOT1 ;JUMP ALWAYS! ; ; CHECK FOR 2-COLUMN DIRECTORY LIST ; CLEARICX}T LDX CSRC LDA ICMD,X CMP #GETCHR BEQ CLERXIT LDA TEMPBUF+1 CMP #'0' BCS EOFEXIT LDY ILEN,X CPY #20 BCC SHFNL DEC ICY}LEN,X LDY #-24 SFTSIZ LDA TEMPBUF+39-256,Y STA TEMPBUF+39-1-256,Y INY BNE SFTSIZ SHFNL LDA TOGGL EOR #$BB STA TOGGL STCZ}A TEMPBUF+19 CLERXIT RTS ; EOFEXIT LDA #$9B CMP TOGGL BEQ CLERXIT DEC IBUF,X INC ILEN,X STA TEMPBUF RTS ; TOGGL DB $9B C[}; ; COPY ONE FILE (AS MANY MEMORY LOADS AS NEEDED) ; COPYFL LDX CSRC LDA ILEN,X ORA ILEN+1,X BEQ NOOUTP LDA SWPFLG BPL WC\}RFILE LDA #LOW[IDD] LDX #HIGH[IDD] JSR PRTMSG JSR CHRGET LDX CDES JSR RESET WRFILE LDX CDES BNE DOWRFI JSR CLEARIT LC]}DX #$00 DOWRFI LDA IOCB,X ;OPEN? BPL PUTOUT ;YES, WRITE NEXT BLOCK ; LDX OPT LDA #8 CPX #'A' ;APPEND? BNE DOPO1 LDA #9 C^}DOPO1 LDX CDES STA IAUX,X JSR ANYDEN ;OPEN THE OUTPUT FILE BMI TOCIOR ; PUTOUT LDX CDES LDY CSRC LDA ILEN,Y STA ILEN,X C_} LDA ILEN+1,Y STA ILEN+1,X LDA IBUF,Y STA IBUF,X LDA IBUF+1,Y STA IBUF+1,X LDA #PUTCHR STA ICMD,X JSR CIOCL ;WRITE NC`}EXT BLOCK OF DATA NOOUTP LDX CSRC LDA ISTAT,X ;EOF? CMP #$88 BEQ CPYXIT LDA SWPFLG BPL RECOPY LDA #LOW[ISD] LDX #HIGHCa}[ISD] JSR PRTMSG JSR CHRGET LDX CSRC JSR RESET JMP RECOPY ; COPYF LDX CSRC STA ICMD,X LDA #$9B STA TOGGL RECOPY LDX CCb}SRC LDA #0 STA TEMPBUF+22 LDA BUFAD LDY BUFAD+1 JSR DEFBUF LDA BUFLEN STA ILEN,X LDA BUFLEN+1 STA ILEN+1,X JSR CIOVCc} ;READ DIRECTORY DATA BPL TOCPFL CPY #$88 ;END OF FILE? BNE TOCIOR ;IF ERROR, ABORT TOCPFL JMP COPYFL TOCIOR JMP CIOER1Cd} ; CPYXIT LDX CDES BEQ NOTCL JSR CLOS2 NOTCL LDX CSRC JMP CLOS2 ; ; FIX UP DOS COPY OPERATION ; DLKMSK = *-1 DB $03,$FF Ce}DLKLOC = *-1 DB $7D,$FD FIXUPDOS LDX SECDAT ;STASH SECTOR SIZE INFO STX SECDAT-$0700+BOOTBUF LDA DLKLOC,X ;STASH LINK LOCf}CATION IN THE SECTOR STX DLINK-$0700+BOOTBUF LDY #$14 NOTRITE LDA #$29 ;AND COMMAND CODE FNDAND INY BMI NOAND CMP BOOTBUCg}F-1,Y BNE FNDAND LDA BOOTBUF,Y CMP #$03 BEQ ANDOK CMP #$FF BNE NOTRITE ANDOK LDA DLKMSK,X ;STASH THE MASK FOR 10 BIT ORCh} 16 BIT LINKS STA BOOTBUF,Y ; NOAND SEC ;WRITE BOOT SECTORS JSR DOBOOT ;DO BOOT I/O ; LDX #$30 ;USE THE DESTINATION IOCi}CB ($30 IS ALWAYS OK) JSR SOPEN ;IF COPYING DOS.SYS (REALLY 'DIAMOND'OS.SYS) DB 0 ;AUX DB DELETE ;CMD DW DOSSYS ;FILECj}NAME -- DELETE EXISTING DOS.SYS ; LDX #$30 ;USE THE DESTINATION IOCB ($30 IS ALWAYS OK) JSR SOPEN DB 0 DB RENAME DW DOSCk}RNM ;MAKE NEW ONE RTS ; ; ; SCAN DIRECTORY AND BUILD THE NEXT FILE NAME ; EXIT WITH NOT-EQUAL IF AT END ; SCNDIR LDA #LOW[DCl}ATA] LDY #HIGH[DATA] JSR DBUF10 LDA #GETREC STA ICMD+$10 LDA #32 STA ILEN+$10 LDA #0 STA ILEN+1+$10 STA CBYTE ;ASSUCm}ME NOT A DIRECTORY JSR CIOCL ;READ A FILE NAME LDA DATA+1 CMP #':' BCS NOTDIR CMP #'0' BCS SCNDX NOTDIR BEQ GOTSPC LDCn}A DATA+10 CMP CBSAV BNE NOTSYS GOTSPC DEC CBYTE NOTSYS LDX FNPT LDY #2 ; MDN1 LDA DATA,Y CMP #' ' BEQ MDN2 STA PAR,X ICo}NX INY CPY #10 BCC MDN1 ; MDN2 LDA #'.' STA PAR,X INX LDY #10 MDN3 LDA DATA,Y CMP #' ' BEQ MDN4 STA PAR,X INY INX Cp} CPY #13 BCC MDN3 MDN4 LDA #'.' CMP PAR-1,X BNE MDN5 DEX MDN5 LDA #0 ;TERMINATE FILE NAME STA PAR,X CLC SCNDX RTS ; GECq}TLIN LDA #LOW[DATA+3] STA FNPTR STA IBUF LDA #HIGH[DATA+3] STA FNPTR+1 STA IBUF+1 LDA #GETREC STA ICMD LDX #1 STX ILCr}EN+1 DEX STX ILEN LDY #0 STY PTR ; CIOCL JSR CIOV TYA BMI CIOER1 RTS CIOER1 STY FR0 LDA #0 STA FR0+1 JSR IFP JSR FCs}ASCII LDY #0 LDA (INBUFF),Y STA CIERC INY LDA (INBUFF),Y STA CIERC+1 INY LDA (INBUFF),Y AND #$7F STA CIERC+2 JSR ECt}RRXIT DB 'Error -- ' CIERC DB '000',$9B,0 ; HEXDEF LDY DATA+3 CPY #$9B BNE GETNO2 RTS ; GETNUM CLC DB $24 ;SKIP SINGLE BCu}YTE ; GETNO2 SEC ROR TEMP2 JSR NXTFLD STY VECTOR STY VECTOR+1 GETND LDA (FNPTR),Y INY CMP #'F'+1 ;IS IT A DIGIT BCS GECv}TNDE SBC #'0'-1 ;NOTE THAT CY=0 BCC GETND1 CMP #10 ;0-9? BIT TEMP2 BPL GOT10 BCC GOT1 ;YES, SHIFT INTO NUMBER CMP #17 Cw};A-F? BCS GOT16 ;YES, HANDLE IT GETND1 SEC ADC #'0'-1 GETNDE STY PTR TAY LDA VECTOR LDX VECTOR+1 RTS ; GOT10 BCS GETND1Cx} PHA ASL VECTOR ROL VECTOR+1 LDA VECTOR LDX VECTOR+1 ASL VECTOR ROL VECTOR+1 ASL VECTOR ROL VECTOR+1 CLC ADC VECTOCy}R STA VECTOR PLA PHP CLC ;[Bob Puff] ADC VECTOR STA VECTOR TXA ADC VECTOR+1 PLP ADC #0 STA VECTOR+1 JMP GETND ;Cz} GOT16 SBC #7 GOT1 ASL VECTOR ROL VECTOR+1 ASL VECTOR ROL VECTOR+1 ASL VECTOR ROL VECTOR+1 ASL VECTOR ROL VECTOR+1 ORC{}A VECTOR STA VECTOR JMP GETND ; ; GETFN -- READ A LINE, GET FILENAME FROM IT ; GETFN LDA #0 STA DOSRNM+1 JSR GETLIN BEQ C|}WCTSTL ; ; GETFN2 -- EXTRACT A FILENAME FROM A LINE ALREADY READ IN ; X IS THE OFFSET IN THE BUFFER ; GETFN2 JSR NXC}}TFLD WCTSTL LDA (FNPTR),Y INY CMP #'?' BEQ SETWC ;IF ? OR * FOUND, CMP #'*' BNE CKEOFN ;SET FLAG, FIND FIRST MATCH SETWCC~} LDA #0 STA CPYTYP BEQ WCTSTL ; CKEOFN CMP #$9B ;IF EOL, CONTINUE WIT SINGLE FILE BEQ FNSET CMP #'.' BEQ WCTSTL CMP #'/C}' BCC FNSET BNE WCTSTL SLSHLP LDA (FNPTR),Y CMP #'S' BNE NCPSYS STA CBSAV BEQ SAVED NCPSYS CMP #'X' BNE NOTSWP LDA #$C}80 STA SWPFLG BMI SAVED NOTSWP STA OPT ;SAVE OPTION CODE SAVED DEY LDA #0 STA (FNPTR),Y INY INY LDA (FNPTR),Y INY CMC}P #'/' BEQ SLSHLP CMP #'.' BCC FNSET CMP #$9B BEQ FNSET DEY ; FNSET STY PTR ;SAVE POINTER TO SECOND ARG. DEY LDA (FNPC}TR),Y STA DELIM LDA #0 STA (FNPTR),Y TAY LDA (FNPTR),Y CMP #'0' BCC DEFDRV CMP #':' BEQ DEFDRV INY BCS LKFCOL TAXC} LDA #':' CMP (FNPTR),Y BEQ DBEFOR DEY STA (FNPTR),Y TXA BNE DGTCOD ; LKFCOL LDA (FNPTR),Y ;SCAN FOR DRIVE ID BEQ DEFC}DRV CMP #':' BEQ DEVINC ;DEVICE INCLUDED INY LDA (FNPTR),Y CMP #':' BEQ DEVINC ; DEFDRV LDA #':' DGTCOD JSR DECFNP DBEFC}OR LDA #'D' JSR DECFNP DEVINC LDY FNPTR LDA FNPTR+1 RTS ; NXTFLD CLC LDA PTR ;MOVE INDEX TO A ADC FNPTR STA FNPTR LDA C}#0 TAY ADC FNPTR+1 STA FNPTR+1 RTS ; DECFNP LDY FNPTR BNE DECFP1 DEC FNPTR+1 DECFP1 DEC FNPTR INC PTR LDY #0 STA (FNC}PTR),Y GETDN1 RTS ; ; REQUIRE A DISK DRIVE (NO FILE SPECIFICATION) ; GETDN2 JSR GETFN2 ;GET NEXT FILE NAME JMP GETDNE ;THEN C}CHECK FOR DRIVE ONLY GETDN JSR GETFN GETDNE STY IBUF+$10 STA IBUF+1+$10 LDY #$FF GETDNL INY TAX LDA (FNPTR),Y BNE GETDNLC} CPX #':' ;ANY FILE NAME INCLUDED? BEQ GETDN1 ;NO, THEN RETURN JSR ERRXIT DB 'File name not allowed!',$9B,0 ; ; UPDATE DEC}NSITY OF DISK IN DRIVE ; GETDEN CMP #':' BNE GTDEN2 LDA DFUNIT GTDEN2 AND #$0F ;MAKE UNIT BINARY LDX #0 STX DAUX+1 INX C}STX DAUX LDX #LOW[TEMPBUF] STX DBUF LDX #HIGH[TEMPBUF] STX DBUF+1 JSR RSEC2 BMI GETDN3 JMP RDCONF ; ; REQUIRE A DISK FC}ILE NAME, SAVING THE POINTER IN IOCB10 ; CKDSK STY IBUF+$10 STA IBUF+1+$10 LDY #0 LDA (FNPTR),Y CMP #'D' BEQ GETDN3 JSRC} ERRXIT DB 'Not a disk file!',$9B,0 ; ; WAIT FOR SOURCE DISK ; CWFSD LDA SWPFLG BMI WFSD GETDN3 RTS ;IF NO WAIT REQUIRED WC}FSD JSR PRINT ISD DB 'Insert SOURCE disk, press ' DC 'R','E','T','U','R','N' DB 0 JSR CHRGET BIT SWPFLG BVS GETDN3 ;IF IC}N DUP-DISK LDX CSRC ; RESET LDY IOCB+1,X STY UNNO LDA IAUX+5,X BEQ NOCHG CMP #3 BCS NOCHG SETDEN STA DKTYPE-1,Y LDX #1C}5 SAVMAP LDA MAPBUF,X STA SAXMAP,X DEX BPL SAVMAP JSR DOFSIN LDX #15 RSTMAP LDA SAXMAP,X STA MAPBUF,X DEX BPL RSTMAP C}; NOCHG RTS ; SAXMAP DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 ; ; RECONFIGURE DENSITY OR CONFIGURATION ; DOFSIN LDX #9 DOFLOP C}LDA WOTDCB,X STA DUNIT+1,X DEX BPL DOFLOP LDX #$31 STX DUNIT-1 LDX UNNO STX DUNIT ;TELL SIO DRIVE TO CONFIGURE LDY DC}KTYPE-1,X ;GET DENSITY/SECTOR SIZE LDA DRVDEF-1,X ;GET DRIVE SPECIFICATION JMP CONFIGR ;GO CONFIGURE DRIVE ; ; SET UP PAR C}AND IOCB10 FOR A DIRECTORY SCAN (MULTI-FILE ACTIVITY) ; SETSCN STA ICMD+$20 LDA #LOW[PAR] LDX #HIGH[PAR] STA IBUF+$20 STXC} IBUF+1+$20 JSR SETPTR LDX #$10 ;OPEN IOCB10 AS DIRECTORY ; OPDIR LDA #6 ;OPEN IOCB AS DIRECTORY STA IAUX,X ; ; OPEN A FILC}E INDEPENDENT OF DRIVE DENSITY ; ANYDEN LDA #0 STA IAUX+1,X STA IAUX+5,X LDA #OPEN JSR SCMD BPL SAVDEN JMP CIOER1 ; SAVC}DEN LDY DUNIT LDA DKTYPE-1,Y STA IAUX+5,X RTS ; ; SET UP 'PAR' FOR A WILD CARD COPY ; DEFPAR JSR SETPTR LDA (FNPTR),Y BNC}E DEFPX STA CPYTYP STA PAR+2,Y LDA #'*' STA PAR,Y STA PAR+1,Y lda #$9B ;termination!!! sta PAR+2,Y ;[Bob Puff] DEFPXC} RTS ; SETPTR LDY #$FF SETLP1 INY LDA (FNPTR),Y STA PAR,Y BNE SETLP1 SETLP2 DEY LDA PAR,Y cmp #'>' ;account for sparta C}type beq SETLP3 ;[Bob Puff] CMP #':' BNE SETLP2 SETLP3 INY STY FNPT RTS ; ; REPORT ERROR, THEN RETURN TO MENU ; ERRXIT C}PLA STA RAMLO PLA STA RAMLO+1 JSR PRTENT ;WRITE ERROR MESSAGE FOLLOWING 'JSR ERRXIT' JMP MENUSL ;THEN RETURN TO MENU ; DC}OSRNM DB 'D',0,':',$60,'OS.SYS,' CKDTST DB 'DOS.SYS',0 OR MESSAGE FOLLOWING 'JSR ERRXIT' JMP MENUSL ;THEN RETURN TO MENU ; D@7 MYDOS 4.51 Source Code Documentation G} Copyright (C) 1988, 1989 by WORDMARK Systems and the authors: Charles G}Marslett 2705 Pinewood Dr. Garland, TX 75042 G} CIS: 73317,3662 UseNet: CHASM@KILLER.DALLAS.TX.US G} and Robert Puff Suite 222 G} 2117 Buffalo Rd. Rochester, NY 14624 G} GEnie: BOB.PUFF This software may be freely used and distributed provided that this copyrigG}ht notice is left intact, and provided that: (1) The source code in machine readable form is provided with G} any binary distribution, or made available at no additional cost to the recipients of the binary distribution. G} (2) A binary version of a derivative work may be sold for a reasonable distribution charge (less than $50), G}and the source code in machine readable format must be available. (3) A derivative work may not impose anG}d restriction on the free distribution of the source code. This is the source coG}de to MYDOS version 4.51. It is written in Atari AMAC format. Use the included A65 assembler, Atari AMAC or the AG}tari MADMAC programs to assemble it. If you do not want a listing, or do not have a printer, and you are assembling witG}h A65, you can specify "-" as the listing file and only the object files will ge generated. If you want a listing yG}ou will probably have to increase the "FILES" configuration parameter to 4 (so the included files can be read -- this G} is the cause of the "I" errors). Here are a few notes on how to create a working copy of MYDOS from tG}he source: (1) It is easiest to use an older version of MYDOS to assemble the new DOS. All filenames used inG} assembling use the D: default drive number; so go to your DOS menu, and set the default drive (and directory) to wG}here your source code resides. The source code and object files will all fit on one double density disk. If you only G} have single density drive(s), then separate the MDOS and MDUP files, but put the object files on the same disk priorG} to BUILDing. (2) Load A65 and enter D:MDOS.ASM as the source file. Press return for the object file and eitG}her - or P: for the listing file. A65 will exit back to the MYDOS menu when the assembly is completed. (3) LG}oad A65 and enter D:MDUP.ASM as the source file. This will assemble the rest of the resident code, and also the non-resG}ident DUP.SYS part. Again A65 will return to the MYDOS menu. (4) If necessary, copy the MDOS.OBJ and MDUP.OBG}J files to a diskette containing BUILD. Now load (and execute) BUILD. This file will read the MDOS.OBJ and MDUP.OG}BJ files you just created. When asked to, press START, and you will be in the new DOS! Now use the [H] command toG} write out DOS files, and you're set! What the files contain: The MDOS.ASM and MDUP.ASM files areG} "header" files, that have some equates, and simply INCLUDE the actual source files (source files are MDOS1.ASM, MDG}OS2.ASM, MDOS3.ASM, MDOS4.ASM, MDUP1.ASM, MDUP2.ASM, MDUP3.ASM, MDUP4.ASM, MDUP5.ASM, MDUP6.ASM and MDUP3.ASM). Be G}warned that there are absolute references that MDUP makes to the MDOS files; these are limited to locations in MDOS1.ASMG} so if the MDOS.ASM or MDOS1.ASM files are modified in any way, these references may need to be changed as well. TG}hey are located in the very beginning of the MDUP.ASM file. The DOS.SYS file itself is contained mostly G}in the MDOSx files; but the code that takes care of MEM.SAV and loading DUP.SYS is in the file MDUP1.ASM. Because G}the DOS is split between two files, you must take note of the last byte the assembly of MDOS.ASM produced, and placG}e this address in the "ORIGIN = xxxx" statement in the MDUP.ASM segment, or the possibility of both files running into eG}ach other will exist. I think that is about it. If you find/correct any bugs, or do any major modiG}fications, Mr. Marslett and I would like to see them. Please see the above references on how to contact us. G} Bob Puff 11/28/88 Charles Marslett 6/14/89 to contact us. Da<